投稿

docker-compose で起動したweb、MySQLに接続できない事象

イメージ
概要 以前作成したPHP + MySQL + LaravelのDockerプロジェクトがコンテナを立ち上げても画面にアクセスできなくなってしまったときの解決方法です。 以前の記事は以下です。 【Laravel + MySQL】Dockerで開発環境を作る https://www.s-watanabe.work/2020/12/laravel-mysqldocker.html 発生事象 コンテナを起動 $ docker-compose up -d Starting laravel-project_mysql_1 ... done Starting laravel-project_app_1 ... done Starting laravel-project_web_1 ... done ブラウザでアクセス いつものようにブラウザでアクセスしますが接続できません。 http://localhost:8000 ※この時Docker側のログには何も出力されません。 MySQLへ接続 MySQLも確認してみましたが同じく接続できなくなりました。 $ mysql -h 127.0.0.1 -u user -ppassword -D test mysql: [Warning] Using a password on the command line interface can be insecure. ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 2 調査・確認 まず以下の記事を参考に新規のDockerプロジェクトが起動・接続できるかを確認しました。 https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-compose-on-ubuntu-20-04-ja # docker-compose はインストール済み $ docker-compose --version docker-compose version 1.26.0, build d

【Azure Functions】Java APIからDB(SQL Server)接続 (Win10)

事前準備 docker-composeを使ってSQL Serverをローカルで起動します。 Docker Desktop for Windows セットアップ ※すでにインストール済みであればこの手順はスキップしてください。 インストール cinst docker-desktop -y 確認 $ docker -v Docker version 19.03.5, build 633a0ea $ docker-compose -v docker-compose version 1.24.1, build 4667896b Hyper-Vの設定 Docker for Windows を使用する場合、Hyper-Vの有効化が必要です。以下手順で有効化します。 「Win + i」で設定画面を開く アプリ > アプリと機能 > プログラムと機能 を開く Windowsの機能の有効化または無効化 を開く Hiper-V にチェックが入っていなければ、チェックして再起動する データベース準備 前回の記事 で c:\TEST 以下にapiを作成したので、ここに docker-compose.yml を作成します。 c:\TEST\docker-compose.yml version: '3' services: db: image: mcr.microsoft.com/mssql/server:latest ports: - "1433:1433" environment: ACCEPT_EULA: Y SA_PASSWORD: test1234@password 起動 $ cd c:\TEST $ docker-compose up -d Starting test_db_1 ... done $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

【Azure Funcsions】ローカルにAzure Functions[Java8]開発環境を構築する(win10)

イメージ
事前準備 chocolatey インストール chocolatey は Windows用の Package Manager (非公式)です。公式のPackageManagementのProviderにもなっています。 インストール chocolatey をインストールするには Power Shell を開いて次のように実行します。 Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) JDK(zulu8) セットアップ JDKは OLACLE のJDKではなく AZUL社のJDKを使います。OLACLE JDKはサポートしていないようで、ビルドするときにエラーになります。 Zulu JDK8 をセットアップするには コマンドプロンプトを管理者で開き次のように実行します。 セットアップ cinst zulu8 -y 環境変数 Zulu JDKのディレクトリを環境変数へ設定します。「システムの環境変数」を開き次のように設定します。 ※Pathについては既存の設定に追記します。 Path=C:\Program Files\Zulu\zulu-8\bin JAVA_HOME=C:\Program Files\Zulu\zulu-8 確認 > java -version openjdk version "1.8.0_292" OpenJDK Runtime Environment (Zulu 8.54.0.21-CA-win64) (build 1.8.0_292-b10) OpenJDK 64-Bit Server VM (Zulu 8.54.0.21-CA-win64) (build 25.292-b10, mixed mode) Maven セットアップ Maven とはJavaプロジェクトの作成、ビルド、実行を行うツールです。 Maven をセットアップするには コマンドプロンプトを管理者で開き次のように実行します。 セットアップ cinst m

【Bootstrap+Drawer.js】Drawerメニュー内にBootstrapのNavbarメニューを組み込む

イメージ
表題の通り、Drawer.jsによりスライドインするメニューの中で、Bootstrapのnavbarを使い開閉可能なサブメニューを実装します。 また、Drawer.jsを使うと実機で見たときにスクロールが正しく機能しなくなったので、そのときにとった対応をメモしておきます。 まずはBootstrapのnavbarとDrawer.jsについて簡単に説明します。 はじめに Bootstrap navbarについて Bootstrapのnavbarは開閉式のメニューを作るのに利用します。 公式 : https://getbootstrap.jp/docs/4.2/components/navbar/ メニューの開閉のコントロールをボタンで行っていますが、テキストにすることもできるので「メインメニュー > サブメニュー」のように実装することも可能です。 実装例 [クリックで表示] 上記イメージの実装が以下のようになります。 開閉ボタンにbuttonタグを使用していますが、これは何でもよくてdata-target属性にcollspaceクラスを持つコンテンツのid属性と併せておけばOKです。 <nav class="navbar navbar-light navbar-expand-md p-1"> <div class="navbar-brand sp"></div> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navmenu" aria-controls="navmenu" aria-expanded="false" aria-label="Toggle navigation"&g

【Android】動画プレイヤーのコードを利用して音楽プレイヤーを作る

イメージ
以前作成した動画プレイヤーのソースコードをほぼそのまま使って今度は音楽プレイヤーを作ってみました。 ※動画プレイヤーについては以下の記事を参考 【Android】VideoViewを使って動画再生アプリを作る① -- ストレージへのアクセス権限を取得 -- 【Android】VideoViewを使って動画再生アプリを作る② -- 内部ストレージのファイル検索 -- 【Android】VideoViewを使って動画再生アプリを作る③ -- カスタムリストビュー -- 【Android】VideoViewを使って動画再生アプリを作る④ -- 全画面で動画再生 -- 【Android】VideoViewを使って動画再生アプリを作る -- 不具合修正、軽微な修正 -- 概要 アプリケーションの特徴 アプリケーションの特徴は以下のとおりで、1-2は動画プレイヤーのコードほぼそのままです。 内部ストレージからmp3ファイルを検索してリスト表示する。 チェックボックスで複数選択し、選択アイテムを連続再生する。 再生中画面では音量調節を可能にする。 再生画面でどのファイルを再生中かわかるようにする。 再生中にホーム画面へ戻ってもアプリケーション実行中はバックグラウンドで再生し続ける。 再生中のイメージ 実装 いくつかこのアプリケーションで新たに対応した内容を記載します。 音量調節 レイアウト 音量調節はSeekBarを使って行います。 <SeekBar android:id="@+id/seekBar" android:layout_width="match_parent" android:layout_height="wrap_content" /> Mp3Activity.java Activity側ではOnSeekBarChangeListenerを設定して、SeekBarのつまみを変更したイベントで音量調節を実行します。 SeekBar seekBar = findViewById(R.id.seekBar); audioManager = (AudioManager)get

【Android】VideoViewを使って動画再生アプリを作る
-- 不具合修正、軽微な修正 --

【Android】VideoViewを使って動画再生アプリを作る で作成したアプリを使っていたところ使いにくい点を発見したのでいくつか改修を入れました。 対応した内容 再生中にスリープモードにしない ファイルサイズを動画の総再生時間に変更 チェックボックスを付けて複数ファイルの再生に対応 再生中にスリープモードにしない この対応は簡単で動画再生するActivityで以下1行入れるだけです。 getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); ファイルサイズを動画の総再生時間に変更 これはトップ画面のファイルリストでファイルサイズを表示していましたが、あまり意味が無いので再生時間を取得して表示するようにしました。以下のようにメソッド化したのでFileオブジェクトを渡してやれば秒数が返ってきます。 /** * 動画ファイル再生時間取得 * @return int */ public static int getDuration(File audioFile) { try { MediaPlayer mediaPlayer = new MediaPlayer(); FileInputStream inputStream = new FileInputStream(audioFile);; FileDescriptor fileDescriptor = inputStream.getFD(); mediaPlayer.setDataSource(fileDescriptor); mediaPlayer.prepare(); int length = mediaPlayer.getDuration(); mediaPlayer.release(); return length / 1000; } catch (Exception e) { return 0; } } これで取得した再生時間をAdapterでListViewにセットするときに以下のように分と秒で分けてやり表示

【Android】カスタムリストビューにCheckBoxを追加したとき別の行までチェックされる事象の対応

AndroidでCheckBox付きのカスタムListViewを実装し、動作確認したところチェックした行以外の行までチェックされてしまう謎現象が発生しました。 カスタムListViewの実装については以下参照 【Android】VideoViewを使って動画再生アプリを作る③ -- カスタムリストビュー -- 今回は単純にチェックボックスと単純な名前を一つだけ持ったListを表示しています。 問題のあるコード Adapterクラス public class ListAdapter extends ArrayAdapter<String> { private int resource; private List<String> items; private LayoutInflater inflater; public ListAdapter(Context context, int resource, List<String> items) { super(context, resource, items); this.resource = resource; this.items = items; this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override public View getView(int position, View convertView, ViewGroup parent) { View view; if (convertView != null) { view = convertView; } else { view = inflater.inflate(resource, null); } TextView itemName = view.findViewById(R.id.item_name)

【Laravel + MySQL】簡単な認証処理を作る

イメージ
前回作成したLaravelアプリケーションに認証処理を実装します。 データベースの作成 ユーザーテーブル作成 Laravel 6.2 にはセットアップした段階で以下の migration 用のコードが入っていますのでこれを実行します。(※今回使用するのはusersテーブルだけです。) 2014_10_12_000000_create_users_table.php 2014_10_12_100000_create_password_resets_table.php 2019_08_19_000000_create_failed_jobs_table.php $ php artisan migrate Migration table created successfully. Migrating: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_000000_create_users_table (0.41 seconds) Migrating: 2014_10_12_100000_create_password_resets_table Migrated: 2014_10_12_100000_create_password_resets_table (0.43 seconds) Migrating: 2019_08_19_000000_create_failed_jobs_table Migrated: 2019_08_19_000000_create_failed_jobs_table (0.31 seconds) ※migrationでエラーになるという場合は 【Laravel + Docker】migration で could not find driver が出たときの対応 が参考になるかもしれません。 ユーザーデータの登録 次にseedという機能を使ってデータを登録します。これはテストデータやマスターデータなど、開発するにあたって必要なデータを登録する機能です。 database/seeds/DatabaseSeeder.php DatabaseSeeder クラスは最初からあるコードで、このrunメソッドに記載されている seed が

【Laravel + MySQL】Dockerで開発環境を作る

イメージ
Docker、docker-compose.yml を利用して次の開発環境を作成する手順をまとめました。 WEBサーバー nginx:1.15.6 データベース mysql 5.7 アプリケーション php 7.2 フレームワーク laravel 6.2 構成について まずプロジェクト全体の構成は以下のようになっています。 . ├── docker │   ├── mysql │   │   └── my.cnf │   ├── php │   │   └── Dockerfile │   └── web │   └── default.conf ├── docker-compose.yml └── laravel-app 基本的には docker-compose.yml を用いてビルドしますが、PHPのみDockerfileを使います。 ※後に記載しますが、pdo_mysqlをコンテナにセットアップしたいためです。(これが分からなくて少し嵌りました。) 各ファイルについての詳細 Docker Compose docker-compose.yml docker-compose.yml の内容は以下です。 version: '3' services: web: image: nginx:1.15.6 ports: - '8000:80' depends_on: - app volumes: - ./docker/web/default.conf:/etc/nginx/conf.d/default.conf - .:/var/www/html app: build: ./docker/php volumes: - .:/var/www/html depends_on: - mysql mysql: image: mysql:5.7 command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci environment:

【Laravel + Docker】migration で could not find driver が出たときの対応

イメージ
Laravel + Dockerの環境を構築し、Laravel導入時から入っているmigrationを実行したところ could not find driver が出てデータベース接続に失敗したのでその際の解決方法をまとめます。 なお、データベースはDockerコンテナにMySQLを作成しています。 環境について Docker docker-compose.yml 環境はウェブサーバー、PHP、データベースでそれぞれコンテナを立てています。 version: '3' services: web: image: nginx:1.15.6 ports: - "8000:80" depends_on: - app volumes: - ./docker/web/default.conf:/etc/nginx/conf.d/default.conf - .:/var/www/html app: image: php:7.3-fpm depends_on: - mysql volumes: - .:/var/www/html mysql: image: mysql:5.7 environment: MYSQL_DATABASE: test MYSQL_USER: user MYSQL_PASSWORD: password MYSQL_ROOT_PASSWORD: password ports: - "3306:3306" volumes: - mysql-data:/var/lib/mysql volumes: mysql-data: migrationエラーについて セットアップ時に入っているmigration Laravelにはセットアップした段階で以下のように3つのmigrationファイルが入っているのでこれを実行してみます。 migrationを実行する $ php artisan migrate --seed Illuminat

【Android】VideoViewを使って動画再生アプリを作る④
-- 全画面で動画再生 --

イメージ
いよいよVideoViewを使って動画ファイルを再生する部分です。 実装 アプリケーションのタイトルバーを消す まずは全画面で表示させるために、アプリケーションのタイトルバーを消します。これにはAndroidManifest.xmlのActivityのテーマ指定を以下のようにします。 AndroidManifest.xml <activity android:name=".Mp4Activity" android:theme="@style/Theme.AppCompat.Light.NoActionBar.FullScreen" /> ナビゲーションバーを消す 次に下段のナビゲーションバー(戻るボタンやホームボタンのバー)を消します。これはActivity内のコードで以下のように制御します。 View decorView = getWindow().getDecorView(); decorView.setSystemUiVisibility( View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION ); 動画再生 Intentで受け取ったファイルパスをVideoViewに読み込みます。 読み込みの完了をOnPreparedListnerより受け取り、再生を開始します。その際に動画縦幅と横幅を比べて横長の動画の場合、画面の向きを変えて最大サイズで再生できるようにしています。 String path = getIntent().getStringExtra("path"); videoView = findViewById(R.id.videoView); videoView.setVideoPath(path); videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mediaPlayer) { if (mediaPlayer.getVideoWidt

【Android】VideoViewを使って動画再生アプリを作る③
-- カスタムリストビュー --

イメージ
ListViewコントロールをカスタマイズして、1つのレコードに様々な情報を表示する方法です。 実装 アイテムクラス まずはListViewの1レコードを表すアイテムクラスの定義です。次の属性を持ちます。 ファイル名 ディレクトリ サイズ 最終更新日 Item.java import java.util.Date; public class Item { private String name; private String path; private long size; private Date lastModified; public void setName(String name) { this.name = name; } public String getName() { return name; } public void setPath(String path) { this.path = path; } public String getPath() { return path; } public void setSize(long size) { this.size = size; } public long getSize() { return size; } public void setLastModified(Date lastModified) { this.lastModified = lastModified; } public Date getLastModified() { return lastModified; } } レイアウト 1レコード分のレイアウトを定義します。 layout/list_item.xml <?xml version="1.0" encoding="utf-8"?> <LinearLay

【Android】VideoViewを使って動画再生アプリを作る②
-- 内部ストレージのファイル検索 --

イメージ
内部ストレージのファイル検索について実装します。またファイルの検索中はプログレスダイアログを表示して操作できない状態にします。 実装 プログレスダイアログを表示 後述しますが、ファイル検索は並列処理(マルチスレッド)で行い、プログレスダイアログの表示をメインスレッドで行います。こうしておかないと画面の更新ができないためです。 final ProgressDialog progressDialog = new ProgressDialog(MainActivity.this); progressDialog.setTitle("ファイル検索中"); progressDialog.setMessage("---"); progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); progressDialog.setCancelable(false); progressDialog.show(); 内部ストレージのパスを取得 まずは検索する場所、内部ストレージのパスは以下で取得できます。また、これはマルチスレッドの中で使うのでfinalで宣言しておきます。 final String path = Environment.getExternalStorageDirectory().getPath(); 並列処理の実装 並列処理は Thread クラスを使用します。なお、通常はスレッド内からメインスレッドのUI (ここではプログレスダイアログ) へのアクセスはできません。これを解決するために Handler クラスを利用します。メインスレッドで定義した Handler クラスの run メソッドによりメインスレッドのUIの操作が可能になります。ここではファイル検索が終了したらメインスレッドのプログレスダイアログを閉じています。 final Handler handler = new Handler(); new Thread(new Runnable() { @Override public void run() { // ファイル検索開始 searchFiles(path);

【Android】VideoViewを使って動画再生アプリを作る①
-- ストレージへのアクセス権限を取得 --

イメージ
小さい子供に動画を見せていると、画面を触って停止してしまったりホーム画面へ戻ってしまったりということがあるので、これを防止した単純な動画再生アプリを作ってみます。 要件 はじめにざっくりとした要件をまとめます。 内部ストレージからmp4ファイルを検索 ※SDカードなどの外部ストレージは今回対象外 動画ファイル名をリスト表示 (できれば動画のイメージを取得してリスト上に表示したい、どうやって取得するんだろう...) ファイル名タップで全画面表示で動画再生 再生中に画面をタップしても何もしない 最後まで再生したら最初に戻って繰り返す 実装については以前作った Json Viewer の大部分が流用できると思うのでこれを改修していく形になります。 https://github.com/s-watanabe-apps/json-viewer.git こちらの実装についての詳細を、次回リスト編と再生編に分けて解説していこうと思います。 実装 内部ストレージからファイルを検索するので、アプリケーションにストレージへのアクセス権限が必要です。 通常権限を取得する場合、Android OSにより以下右のダイアログを出してユーザーに許可を求めます。しかし何のために該当の権限を利用するかこのダイアログだけではわかりません。左画像のように権限の利用目的を明示してあげるのが親切な設計です。 ※アプリケーションから権限の取得方法には以前 記事 にしましたが、今回は以下のように利用目的の表示を明示するようにしました。 権限設定 AndroidManifest.xml AndroidManifest.xmlに以下を追加します。 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 権限の確認と利用目的の説明 まずは権限が許可されているかをチェックし、許可されていない場合(もしくは初回起動のとき)に利用目的をユーザーに明示します。そこでOKを押してもらったときに requestP

【Java】ObjectMapperでJSONデータを変数に取り込む

ObjectMapperを使えばどんな型のjsonデータであっても変数に取り込んだり、またオブジェクトからjsonを出力したりすることができます。 過去に紹介した JSONObjectを使う方法 より全然楽です。 連想配列のJSON JSONデータ JSONデータは以下を使用します。 { "member_id":"1, "name":"Taro", "age":30, "address":"Tokyo" } JSONデータのParse処理 package com.example; import java.util.Map; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; public class App { public static void main(String[] args) { String json = "{\"member_id\":1,\"name\":\"Taro\",\"age\":30,\"address\":\"Tokyo\"}"; try { Map<String, Object> map = new ObjectMapper().readValue( json, new TypeReference<Map<String, Object>>() { }); for(Map.Entry<String, Object> entry : map.entrySet()){ System.out.printl