Docker for WindowsでLaradock(+MySQL)の環境構築

はじめに

Docker for WindowsでLaradockの環境構築をして、Webアプリが作れるところまで記載してます。

DBに関してはMySQL+phpmyadminを利用。

※Dockerのインストールに関しては割愛。

Docker学んでみた

事前知識

✅Laravelの推奨環境

PHP ver7以上
MySQL ver5.7以上

✅Dockerの重要頻出コマンド

Hyper-VはONにしないと起動しない(※Android StudioはOFFにしないと起動しないので注意)。

$ docker images // イメージの一覧確認
$ docker ps // 動いているコンテナの確認
$ docker rm <コンテナID> // コンテナ削除
$ docker-compose up -d nginx mysql workspace phpmyadmin // 起動
$ docker-compose stop // 停止
$ docker-compose exec workspace bash // コンテナ内へのログインはbashを付ければOK
$ docker-compose exec workspace php artisan migrate // laradockディレクトリでこのようなコマンドを打つとターミナルは要らず処理できる

✅Laradockのデフォルトのポート番号

nginx 80
mysql 3306
phpmyadmin 8081

環境構築

✅Laradockの起動 ※Dockerのインストール後です

$ mkdir laravel_app // フォルダ作成
$ cd laravel_app
$ git clone https://github.com/laradock/laradock.git // laradockをクローン
$ cd laradock
$ cp env-example .env // .envの作成
$ vim .env // .envの編集
APP_CODE_PATH_HOST=../laravel #laravelのプロジェクトファイル名に書き換え
DATA_PATH_HOST=../data #複数データを参照してしまう可能性があるため一意に指定
COMPOSE_PROJECT_NAME=laravel_sample_5.5 #dockerのコンテナ名が一意になる
MYSQL_VERSION=5.7 #latestから変更。※MySQLのバージョンは8.0以上になっているとセキュリティの関係でDockerがうまく動作しない
# DB_HOST=mysql #5/19追記:DB_HOSTを削除しても起動した。

また、MySQL Notifierインストールされてる方は停止させておく。

⭐起動⭐コンテナの初期化(実行コマンド※Dockerアプリは起動した状態※)

$ docker-compose up -d nginx mysql workspace phpmyadmin

※初回起動は大体30分くらいかかるので要注意!!!また、マウントの関係上、今後すべてのディレクトリ名変えるとエラーになるので要注意。

✅プロジェクトの作成

プロジェクト作成

$ docker-compose exec workspace composer create-project --prefer-dist laravel/laravel . "6.8.*"
$ docker-compose exec workspace composer create-project --prefer-dist laravel/laravel . "5.5.*"

※プロジェクト生成に10分くらいかかる。
※dockerコンテナ内のvar/www(ここがlaravelディレクトリと紐づいている)に作成される。

以下でアクセスできる。(Dockerの場合はphp artisan serveが不要)

Laravelアプリ トップ画面 http://localhost/
phpmyadmin トップ画面 http://localhost:8081/

phpmyadminにログインしてDB作成。(もちろんコマンドでも可)

サーバ名:mysql
ユーザー名:root
パスワード:root

laravel/.envファイル編集

DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=larasns // phpMyAdminで作ったDB名に合わせる。
DB_USERNAME=root
DB_PASSWORD=root

コントローラー作成

$ docker-compose exec workspace php artisan make:controller ArticleController
Controller created successfully.

マイグレーションファイル作成

$ docker-compose exec workspace php artisan make:migration create_articles_table --create=articles
Created Migration: 2020_03_24_092458_create_articles_table

マイグレート

$ docker-compose exec workspace php artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_000000_create_users_table (0.13 seconds)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated: 2014_10_12_100000_create_password_resets_table (0.13 seconds)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated: 2019_08_19_000000_create_failed_jobs_table (0.07 seconds)
Migrating: 2020_03_24_092458_create_articles_table
Migrated: 2020_03_24_092458_create_articles_table (0.05 seconds)

※phpMyAdminでDBを作成しておかないとマイグレートできないので注意してください!!

✅Docker使う際の主要コマンド

起動の確認

statusがupになっていれば起動中です。

$ docker ps

サービスの終了

docker-compose stop

再起動

docker-compose up -d nginx mysql workspace phpmyadmin

永続化の仕組み理解

※5/19追記

「Laravel(+Vue.js)でSNS風Webサービスを作ろう!」をWindows+Laradock+PostgreSQL(永続化対応)でやってみた

PostgreSQLでは永続化できないのに、MySQLだといとも簡単に永続化できてしまいます。気持ち悪いので原因を探りたいと思います(PSQLは未解決)。

docker-compose.ymlの392行目

mysql:
  volumes:
    - ${DATA_PATH_HOST}/mysql:/var/lib/mysql // .envから../dataを代入
    - ${MYSQL_ENTRYPOINT_INITDB}:/docker-entrypoint-initdb.d // .envから./mysql/docker-entrypoint-initdb.dを代入

(ゲスト側の確認)mysqlコンテナへログイン

docker-compose exec mysql bash
root@78f0d9649369:/# cd var/lib/mysql
root@78f0d9649369:/var/lib/mysql# ls
auto.cnf    ca.pem           client-key.pem  ib_buffer_pool  ib_logfile1  ibtmp1   mysql               private_key.pem  server-cert.pem  sys
ca-key.pem  client-cert.pem  docker_mysql    ib_logfile0     ibdata1      larasns  performance_schema  public_key.pem   server-key.pem

試しにtestディレクトリを作ってみる。

root@78f0d9649369:/var/lib/mysql# mkdir test
root@78f0d9649369:/var/lib/mysql# ls
auto.cnf    ca.pem           client-key.pem  ib_buffer_pool  ib_logfile1  ibtmp1   mysql               private_key.pem  server-cert.pem  sys 
ca-key.pem  client-cert.pem  docker_mysql    ib_logfile0     ibdata1      larasns  performance_schema  public_key.pem   server-key.pem   test

ローカルで確認。同期されていることを確認!!

PS C:\Users\chonm\docker_mysql\data\mysql> ls
~~~~
d-----       2020/05/19     17:41                test

こんなに簡単だとなぜPostgreSQLは同期されないのか逆に困惑する。。。

Laravelで簡単なページを作成するまで

上記記事では、「永続化についてpostgresの永続化はwindowsだと上手くいかずnamed volumeを作成してそこを指定するというのが一般的です。」と記されている。

以前作成したLaravelプロジェクトをDocker下で起動させる

①Laradockが入ったディレクトリに以前作成したプロジェクトを移動。

②プロジェクト名をlaravelに変更する(※以前あったものはlaravel-pastなりわかるように変更しておく)。

③laravel/.envを編集

④docker-compose down&upでコンテナを新しく作成。

⑤マイグレーション docker-compose exec workspace php artisan migrate

⑥確認

ユーザー登録と投稿データも動作確認がてらテスト。問題なく動作!!

⑦試しにコンテナを削除して再作成。 docker-compose down&up

データの永続化に成功◎

この環境下でアプリ制作するのが良さそう。

それとこれを通じてなんとなくアプリ併用の仕組みもわかった気がする。

フォルダを複製して使ってみる

laradockやlaravelプロジェクトがまとめて入ったディレクトリを複製して起動するか試してみました。

こんな感じ。

laradockディレクトリに行って確認。起動成功。

\laravel-sns-mysql-copy\laradock> docker-compose up -d nginx mysql workspace phpmyadmin
  Recreating laravel-sns-mysql_mysql_1 ... done
  Recreating laravel-sns-mysql_docker-in-docker_1 ... done
  Recreating laravel-sns-mysql_workspace_1 ... done
  Recreating laravel-sns-mysql_phpmyadmin_1 ... done
  Recreating laravel-sns-mysql_php-fpm_1 ... done
  Recreating laravel-sns-mysql_nginx_1 ... done
\laravel-sns-mysql-copy\laradock> docker ps
  CONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS                          PORTS                                              NAMES
  19898194745f        laravel-sns-mysql_nginx        "/bin/bash /opt/star…"   5 seconds ago       Up 3 seconds                    0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp, 81/tcp   laravel-sns-mysql_nginx_1     
  7a72369b9704        laravel-sns-mysql_php-fpm      "docker-php-entrypoi…"   16 seconds ago      Up 15 seconds                   9000/tcp                                           laravel-sns-mysql_php-fpm_1   
  4b690a3c1caf        laravel-sns-mysql_phpmyadmin   "/docker-entrypoint.…"   17 seconds ago      Up 16 seconds                   0.0.0.0:8080->80/tcp                               laravel-sns-mysql_phpmyadmin_1
  01b7911674d5        laravel-sns-mysql_workspace    "/sbin/my_init"          18 seconds ago      Up 16 seconds                   0.0.0.0:2222->22/tcp                               laravel-sns-mysql_workspace_1
  8577775c7397        laravel-sns-mysql_mysql        "docker-entrypoint.s…"   19 seconds ago      Up 18 seconds                   0.0.0.0:3306->3306/tcp, 33060/tcp                  laravel-sns-mysql_mysql_1
  52450dbb34bf        docker:dind                    "dockerd-entrypoint.…"   20 seconds ago      Up 19 seconds                   2375-2376/tcp                                      laravel-sns-mysql_docker-in-docker_1

👉なんとなくXAMPPではなくDockerを使うメリットを感じ始めた。

躓きポイント

✅php-fpmがエラーになる

👉再起動したら直りました。原因不明。

以前はエラー起きなかったのに。。。

\laradock> docker-compose up -d nginx mysql workspace phpmyadmin
Starting laravel-sns-mysql_mysql_1 ...
Starting laravel-sns-mysql_mysql_1 ... done
laravel-sns-mysql_workspace_1 is up-to-date
Starting laravel-sns-mysql_php-fpm_1 ...
Starting laravel-sns-mysql_php-fpm_1 ... error

ERROR: for laravel-sns-mysql_php-fpm_1 Cannot start service php-fpm: error while creating mount source path '/host_mnt/c/Users/chonm/laravel-sns-mysql/laradock/php-fpm/php7.3.ini': mkdir /host_mnt/c/Users/chonm/laravel-sns-mysql/laradock/php-fpm/php7.3.ini: file exists

ERROR: for php-fpm Cannot start service php-fpm: error while creating mount source path '/host_mnt/c/Users/chonm/laravel-sns-mysql/laradock/php-fpm/php7.3.ini': mkdir /host_mnt/c/Users/chonm/laravel-sns-mysql/laradock/php-fpm/php7.3.ini: file exists
ERROR: Encountered errors while bringing up the project.

こちら参考にしたところ既に修正されている。。。

もろもろ起動できなくなっている。。。

\laradock> docker-compose ps
Name Command State Ports
-----------------------------------------------------------------------------------------------------
laravel-sns-mysql_docker-in-docker_1 dockerd-entrypoint.sh Exit 1
laravel-sns-mysql_mysql_1 docker-entrypoint.sh mysqld Exit 1
laravel-sns-mysql_nginx_1 /bin/bash /opt/startup.sh Exit 1
laravel-sns-mysql_php-fpm_1 docker-php-entrypoint php-fpm Up 9000/tcp
laravel-sns-mysql_phpmyadmin_1 /docker-entrypoint.sh apac ... Up 0.0.0.0:8080->80/tcp
laravel-sns-mysql_workspace_1 /sbin/my_init Up 0.0.0.0:2222->22/tcp

docker_mysqlからディレクトリ名を変えたことが原因かな??

✅docker-compose upでMySQLが起動しない問題

原因のほとんどはポート被り。現在は3306で起動させています。

対処法:①ローカルに落としているMySQLをオフにする②XAMPPのMySQLをオフにする

以下、エラー発生時の例。3306ポートが使えないの図。

対処法①ローカルに落としているMySQLをオフにする

Windowsでしたら以下のようにタスクバーを確認してください。

MySQLがいたらそいつが原因の可能性が高いです。こいつを停止しましょう。

コマンドを実行すると3306でも起動する。

対処法②XAMPPのMySQLをオフにする

上記と同じように、もしXAMPPでMySQLを起動していたとしたらエラーの原因になります。

こちらもStopしてから再起動すれば起動します。

ちなみに両方共存させたくてポート番号を変更したい場合は以下です。

.envファイル上で3306と記載の部分を3307に変更して再度compose upすると3307で起動します。

✅8080ポートが使えない問題

5/19追記:Laradockをクローンしてきた当初のデフォルトデータで試したところ問題なく動作。laradock/.envのポート番号とdocker-compose.yamlのポート番号が異なっていたことが原因でした。当時、環境変数の理解もなく色々弄っていたことが起因。。。

Creating laravel-sns-mysql_mysql_1 ... done
Creating laravel-sns-mysql_workspace_1 ... 
Creating laravel-sns-mysql_workspace_1 ... error
WARNING: Host is already in use by another container

ERROR: for laravel-sns-mysql_workspace_1 Cannot start service workspace: driver failed programming external connectivity on endpoint laravel-sns-mysql_workspace_1 (d65374166211eb5d0ea1ef033ca5bccd4dae8d5c3a6fd470975eb0dbd26cd391): BinCreating laravel-sns-mysql_phpmyadmin_1 ... done

ERROR: for workspace Cannot start service workspace: driver failed programming external connectivity on endpoint laravel-sns-mysql_workspace_1 (d65374166211eb5d0ea1ef033ca5bccd4dae8d5c3a6fd470975eb0dbd26cd391): Bind for 0.0.0.0:8080 failed: port is already allocated
ERROR: Encountered errors while bringing up the project.

対処法:ポート番号を変更する。

docker-compose.ymlのphpmyadminのポート番号を8081に変更。

※左側が外部からのアクセス時のポート、右側が docker コンテナからアクセスする時のポート番号

//ポートのみ変更した場合
phpmyadmin:
      build: ./phpmyadmin
      environment:
        - PMA_ARBITRARY=1
        - MYSQL_USER=root
        - MYSQL_PASSWORD=password
        - MYSQL_ROOT_PASSWORD=password
    ports:
    - 8081:80

//サーバ名を調べるのに試行錯誤したパターン。※ログインエラー。
mysql:
      build:
        context: ./mysql
        args:
          - MYSQL_VERSION=${MYSQL_VERSION}
      environment:
        - MYSQL_DATABASE=DB
        - MYSQL_HOST=DB
        - MYSQL_USER=root
        - MYSQL_PASSWORD=password
        - MYSQL_ROOT_PASSWORD=password
        - TZ=${WORKSPACE_TIMEZONE}

phpmyadmin:
      build: ./phpmyadmin
      environment:
        - PMA_ARBITRARY=1
        - PMA_HOST=mysql
        - PMA_USER=root
        - PMA_PASSWORD=password
      ports:
        - 8081:80

コマンドを実行すると起動。

※8080ポートが何に使用されているのか原因は掴めませんでした。。。わかり次第追記します。

✅phpMyAdminログインできない問題

対処法:①.envファイルに従う②rootユーザーでログインする。

http://localhost:8081でphpmyadminへアクセス。

以下の画面になります。

XAMPPではこのような画面は出ないので困惑する人も多いはず。。。

対処法:①.envファイルに従う

※こちらは編集権限がありません。(意味ない。。。)

laravel-practiceの.envに従い入力したところログインに成功。
サーバ:mysql
ユーザー:default
パスワード:secret

以下参照

DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3307
DB_DATABASE=default
DB_USERNAME=default
DB_PASSWORD=secret

対処法:②rootユーザーでログインする。

実は.envファイルに以下のような記載があります。

MYSQL_ROOT_PASSWORD=root

ユーザー:root
パスワード:root

以上で、ログインすると編集できます◎

また、コマンドラインでも以下のように実行可能です。

mysql -u root -p root //こちらからもアクセス可能
create database default; //DB作成

未検証備忘録

✅PHPのバージョン変更 参考

※現状不便を感じていないので未検証だが、簡単にできそう。

laradock/.envを変更するだけ。

### PHP Version ###########################################

# Select a PHP version of the Workspace and PHP-FPM containers (Does not apply to HHVM).
# Accepted values: 7.4 - 7.3 - 7.2 - 7.1 - 7.0 - 5.6
PHP_VERSION=7.3

確認はこんな感じでできる。 参考

\laravel-sns-mysql-copy\laradock> docker-compose exec --user=laradock workspace bash
laradock@01b7911674d5:/var/www$ php -v
PHP 7.3.14-1+ubuntu16.04.1+deb.sury.org+1 (cli) (built: Jan 23 2020 13:58:58) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.14, Copyright (c) 1998-2018 Zend Technologies
with Zend OPcache v7.3.14-1+ubuntu16.04.1+deb.sury.org+1, Copyright (c) 1999-2018, by Zend Technologies

✅MySQLに加えてPostgreSQL(※永続化できていないので未検証欄)もすぐコンテナ作成できるようにする

データを複製したことを通じて、一度コンテナを作成したディレクトリに関してはコンテナ作成が速いことに気付きました。

なのでPostgreSQLもすぐ起動できるようにしてみます。

docker-compose up -d workspace php-fpm nginx postgres

懸念点:laradock/postgres/Dockerfileを敢えて変更せずに試してみる。 参考

FROM postgres:11.6 // やんばるさん教材
FROM postgres:alpine // デフォルト。ちなみにalpineだと少し速いらしい。11-alpine なども可能ぽい。

起動

WARNING: Image for service postgres was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating laravel-sns-mysql_docker-in-docker_1 ... done
Creating laravel-sns-mysql_postgres_1 ... done
Creating laravel-sns-mysql_workspace_1 ... done
Creating laravel-sns-mysql_php-fpm_1 ... done
Creating laravel-sns-mysql_nginx_1 ... done

確認

docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4be59100880a laravel-sns-mysql_nginx "/bin/bash /opt/star…" 3 minutes ago Up 3 minutes 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp, 81/tcp laravel-sns-mysql_nginx_1
188ee2979144 laravel-sns-mysql_php-fpm "docker-php-entrypoi…" 3 minutes ago Up 3 minutes 9000/tcp laravel-sns-mysql_php-fpm_1
26ab728fab6e laravel-sns-mysql_workspace "/sbin/my_init" 3 minutes ago Up 3 minutes 0.0.0.0:2222->22/tcp laravel-sns-mysql_workspace_1
d192f7268485 laravel-sns-mysql_postgres "docker-entrypoint.s…" 3 minutes ago Up 3 minutes 0.0.0.0:5432->5432/tcp laravel-sns-mysql_postgres_1
015db3e3e459 docker:dind "dockerd-entrypoint.…" 3 minutes ago Up 3 minutes 2375-2376/tcp laravel-sns-mysql_docker-in-docker_1

localhostへアクセス。PostgreSQLのDB作成すれば行けそう。

DB作成。

docker-compose exec workspace psql -U default -h postgres
default=# create database larasns;
>> CREATE DATABASE
default=# \q

laravel/.envを編集

※変更前

DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=larasns
DB_USERNAME=root
DB_PASSWORD=root

※変更後

DB_CONNECTION=pgsql
DB_HOST=postgres
DB_PORT=5432
DB_DATABASE=larasns
DB_USERNAME=default
DB_PASSWORD=secret

マイグレーションできた。

docker-compose exec workspace php artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (0.13 seconds)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (0.01 seconds)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated:  2019_08_19_000000_create_failed_jobs_table (0.01 seconds)
Migrating: 2020_03_17_170647_create_articles_table
Migrated:  2020_03_17_170647_create_articles_table (0.03 seconds)
Migrating: 2020_03_18_205404_create_likes_table
Migrated:  2020_03_18_205404_create_likes_table (0.01 seconds)
Migrating: 2020_03_19_172238_create_tags_table
Migrated:  2020_03_19_172238_create_tags_table (0.01 seconds)
Migrating: 2020_03_19_173524_create_article_tag_table
Migrated:  2020_03_19_173524_create_article_tag_table (0.01 seconds)
Migrating: 2020_03_19_183737_create_follows_table
Migrated:  2020_03_19_183737_create_follows_table (0.01 seconds)

アクセスすると表示されて動作確認もOK。

ただし、docker-compose down&upでコンテナを再生成するとやはり永続化はできていなかった。

※PostgreSQL起動させると過去に作成したVuesplashのDBも起動してる。。。

その後、再度docker-compose downして、mysqlを起動

docker-compose up -d nginx mysql workspace phpmyadmin

laravel/.envも編集前に戻してlocalhostへアクセス。無事確認できた。便利◎

✅HerokuへのMySQLでのデプロイ

参考:入門Laravelチュートリアル (11) ToDoアプリをHerokuにデプロイする

せっかく使っているのであればDockerコンテナごとデプロイしてみたいがどうしたらできるか。。。

やんばるさん教材も上記教材もPostgreSQLでのデプロイなので、MySQLでHerokuに上げられるよう調べる必要あり。

どうやらMySQLはデフォルトで使えないので下記コマンドが必要になるっぽい。 参考

heroku addons:add cleardb

※ドキュメントは「laravel mysql heroku」で調べただけでも沢山出てきたので困ることはなさそう。

✅DockerコンテナごとAWSへデプロイ

参考:
AWS EC2にLaravel+Laradockをデプロイ(イントロ)
【Laravel, AWS】AWS EC2にdockerを使ったLaravelアプリをデプロイする話
知識0から Docker 環境を AWS の ECS でデプロイするまで
知識ゼロのAWSのEC2でdockerを使ってlaravelを立ち上げる方法

これがいまやりたいこと。割とドキュメント多めなのでなんとかなりそう。

おわりに

1つのプロジェクト生成まで小1時間かかる印象なので使いまわすようにしたい。。。

5/19追記:なんとなくではあるものの、Docker環境下でアプリ制作してみよう!といったところまでは来れた気がする。

以前書いた記事が、自分で見返すにしても衝撃的なわかりにくさで困惑したので書き直しました。笑

以前の格闘感丸出しの記事は以下になります。

(昔の記事見返したくない。。。こういった記事は別途タグ分けて保管していくことにします。)

【Laravel】Docker for WindowsでLaradock(+MySQL)に挑戦してみた。【備忘録】

✅参考記事

Windows10でLaradockを使ってLaravel 5.5環境を作る
https://qiita.com/sket88/items/4de708ce394179c61d8a

DockerでMySQL複数バージョンを共存させる
https://qiita.com/tanakaworld/items/427b94ea0435b5dccfa2

LaradockのMySQLに接続できなくてはまった話
https://qiita.com/dnrsm/items/4bd078c17bb0d6888647

laradockの環境設定からMySQL接続まで
https://qiita.com/yknsmullan/items/dea4102cf14b1b66e5af

docker起動でportが確保できないエラーの解決
https://nijoen.net/blog/773/

Dockerでコンテナの停止・削除ができなくなった時の対処法
https://qiita.com/musatarosu/items/31d6293a93e75ca6073e

docker docker-compose コマンド
https://qiita.com/souichirou/items/6e701f6469822a641bdd

✅備忘録

PostgreSQLの起動

docker-compose up -d workspace php-fpm nginx postgres // 上記、MySQLで一度起動したLaradockの場合は最初にPostgreSQLのインストールが始まる。

コメントを残す