Windows10でLaradockを使ってLaravel 5.5環境を作る


はじめに
---
こんにちは、株式会社シーエー・アドバンス技術統括本部の@sk888です。
カスタマーエンジニア(H/W修理)→NWエンジニア→セキュリティエンジニア(SIEM導入)ときて、
今年の5月からセキュリティエンジニア(脆弱性診断)にジョブチェンジしました。
今回はジョブチェンジのために実施したWEBアプリケーション開発研修の中から、Laradockの
導入について記事にしようと思います。


環境と使用したSoftwareなど
---
Winodws10Pro 64bit
Docker For Windows(CE)
Git
Cmder(ターミナルソフト)

※64bit版のWindows10Pro及びEnterprise,Education(ビルド14393以降）エディションじゃない方は、OS Nativeの仮想化プラットフォームであるHyper-Vが使えないのでDocker for Windowsが使えません。
お金の力でアップグレードするか、Hyper-Vの代わりにOracle Virtual Boxを使用するDocker Toolboxをインストールできます。ただ、この記事の手順がDocker Toolboxでも同様かは確認出来ていません。
Docker for Windowsのインストールに必要なシステム要件は下記のサイトのSystem Requirements:に記載されています。

[Install Docker for Windows](https://docs.docker.com/docker-for-windows/install/)

システム要件を満たさない場合は、Note:に下記の記載があります。
```
 If your system does not meet the requirements to run Docker for Windows, you can install Docker Toolbox, which uses Oracle Virtual Box instead of Hyper-V.
```

google翻訳
```
システムがDocker for Windowsを実行するための要件を満たしていない場合、Hyper-Vの代わりにOracle Virtual Boxを使用するDocker Toolboxをインストールできます。
```
準備
---
まずはGitとDocker For Windows(CE)をインストールして下さい。
それぞれインストール方法については検索すれば簡単に出てくると思います。
私は下記のサイトを参考にさせて頂きました。

**Docker**

* [[Docker]入門から導入までに読むべき記事集](https://qiita.com/ozota/items/8934155e081776916c0a#_reference-2def5c15902a1685412e)
* [Docker CE for WindowsでDockerを学ぶ (version 18.03.1-ce-win65)](https://qiita.com/rubytomato@github/items/62161083b1db57b55878)

**Git**

* [【初心者向け】Gitのインストール方法をわかり易く解説（画面付き）](https://eng-entrance.com/git-install)
* [自分用 Git For Windowsのインストール手順](https://qiita.com/toshi-click/items/dcf3dd48fdc74c91b409)

ターミナルはコマンドプロンプトとPowershellが使えるようですが、私はどちらもあまり好きではないので、
良さげなターミナルソフトを探してインストールしました。

[Cmder | Console Emulator](http://cmder.net/)


Laradockのダウンロード
---
それではさっそく始めましょう。
まずはLaradockを配置するディレクトリを適当な場所に作成します。
ディレクトリ名はとりあえず「MyWork」にしました。
作成した「MyWork」に移動します。

```sh
>mkdir MyWork
>cd MyWork
```


git cloneコマンドでLaradockのダウンロードを行います。

```sh
>git clone https://github.com/laradock/laradock.git
Cloning into 'laradock'...
remote: Enumerating objects: 8295, done.
remote: Total 8295 (delta 0), reused 0 (delta 0), pack-reused 8295R
Receiving objects: 100% (8295/8295), 7.87 MiB | 85.00 KiB/s, done.
Resolving deltas: 100% (4388/4388), done.
```


ダウンロードが完了すると「laradock」ディレクトリが作成されているので、「laradock」に移動します。

```sh
>ls
laradock/
>cd laradock
```

.envファイルの作成
---
設定ファイルとなる.envファイルを作成します。
laradockディレクトリには.envファイルの元となるenv-exampleファイルがあるので
それをコピーします。

```sh
>cp env-example .env
```

コンテナの立ち上げ
---
設定ファイルを作成したら、docker-compose upコマンドでコンテナの立ち上げを行います。
コンテナのビルドから行っているので数分から数十分ほどかかるかもしれません。

```sh
>docker-compose up -d nginx mysql workspace phpmyadmin
～～～～～～～～～～～～略～～～～～～～～～～～～～
creating laradock_docker-in-docker_1 ... done
creating laradock_mysql_1            ... done
creating laradock_workspace_1        ... done
creating laradock_phpmyadmin_1       ... done
creating laradock_php-fpm_1          ... done
creating laradock_nginx_1            ... done
```

docker-compose psコマンドでコンテナの状態を確認出来ます。
指定したパスが見つかりませんとか言われてしまうかもしれませんが、コマンドの結果は正常に表示されているのでスルーでお願いします。

```sh
>docker-compose ps
指定されたパスが見つかりません。
           Name                          Command                State                      Ports
------------------------------------------------------------------------------------------------------------------
laradock_docker-in-docker_1   dockerd-entrypoint.sh            Up         2375/tcp
laradock_mysql_1              docker-entrypoint.sh mysqld      Up         0.0.0.0:3306->3306/tcp, 33060/tcp
laradock_nginx_1              nginx                            Up         0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
laradock_php-fpm_1            docker-php-entrypoint php-fpm    Up         9000/tcp
laradock_phpmyadmin_1         /run.sh supervisord -n           Up         0.0.0.0:8080->80/tcp, 9000/tcp
laradock_workspace_1          /sbin/my_init                    Up         0.0.0.0:2222->22/tcp
```

Laravelプロジェクトの作成
---
WorkSpaceコンテナにログインし、Laravelプロジェクトを作成します。
まずはlaradock_workspace_1コンテナにlaradockユーザーでログインします。
ログイン後はカレントディレクトリが「/var/www」になっていると思います。

```sh
>docker-compose exec --user=laradock workspace bash
laradock@10c23aa8f321:/var/www$
```

Laravleの新規プロジェクトを作成します。"MyProject"の部分は任意のプロジェクト名にして下さい。
--prefer-distオプションでバージョン5.5を指定しています。
コマンド実行後はプロンプトが帰ってくるまで辛抱強く待ちましょう。

```sh
>composer create-project laravel/laravel MyProject --prefer-dist "5.5.*"
```

プロジェクト作成後、プロジェクト名のディレクトリが「/var/www」に作成されているので確認しましょう。
このディレクトリの中にLaravelのファイル一式が入っています。

```sh
>ls
laradock  MyProject
```

満足するまでLaravelのディレクトリを眺めたら、一旦WorkSpaceコンテナからログアウトします。

```sh
>exit
```

.envファイルの編集
---
laradockディレクトリにある.envファイルを開き共有ディレクトリの設定を変更します。
DB_HOST=mysqlも末尾に追加します。

```ini:.env
###########################################################
###################### General Setup ######################
###########################################################

### Paths #################################################

# Point to the path of your applications code on your host
#APP_CODE_PATH_HOST=../            ←既存設定をコメントアウト
APP_CODE_PATH_HOST=../MyProject    ←laravelのプロジェクトファイル名に書き換える

～～～～～～～～～～～～～～～～略～～～～～～～～～～～～～～～

DB_HOST=mysql          ←一番下に追加
```

編集を終えたらコンテナを再起動します。

```sh
>docker-compose stop
Stopping laradock_nginx_1            ... done
Stopping laradock_php-fpm_1          ... done
Stopping laradock_workspace_1        ... done
Stopping laradock_docker-in-docker_1 ... done
Stopping laradock_phpmyadmin_1       ... done
Stopping laradock_mysql_1            ... done

>docker-compose up -d nginx mysql workspace phpmyadmin
Recreating laradock_docker-in-docker_1 ... done
Starting laradock_mysql_1              ... done
Starting laradock_phpmyadmin_1         ... done
Recreating laradock_workspace_1        ... done
Recreating laradock_php-fpm_1          ... done
Recreating laradock_nginx_1            ... done
```

ブラウザでhttp://localhost にアクセスします。Laravelの初期設定のWelcome画面が表示されます。
![laravel.png](https://qiita-image-store.s3.amazonaws.com/0/255483/0b4d8ba5-bba3-9a38-f6c7-fa2f22e1b62d.png)

この画面が表示されるととりあえず成功です。
ただ、この時点ではLaravel側のDB接続設定がLaradocのコンテナの設定と合っていないのでDBへの接続が出来ていません。

Laravelプロジェクトディレクトリの.envファイルの編集
---
Laravelのプロジェクトディレクトリ内にある.envファイルを編集する必要があります。

```ini:.env
DB_HOST=127.0.0.1
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret
↓↓↓↓↓↓↓↓↓↓↓↓↓↓
DB_HOST=mysql
DB_DATABASE=default
DB_USERNAME=default
DB_PASSWORD=secret
```

.envファイル編集後、WorkSpaceコンテナでphp artisan migrateコマンドを実行します。

```sh
>docker-compose exec --user=laradock workspace bash

>php artisan migrate
```

これで成功すればいいのですが、MySQL8.0からセキュリティが強化されユーザー作成時のパスワード生成方式が選択できるようになったせいで、デフォルトで従来の方式を設定しないとエラーが出るみたいです。
下記のサイトにわかりやすくまとめられていたので解決方法を参考にさせて頂きました。

[【Docker】MySQL8.0系を使う時に発生する問題について](https://blog.websandbag.com/entry/2018/05/17/121730)

コンテナの停止と削除
---
docker-compose downコマンドでコンテナの停止と削除を行います。

```sh
>docker-compose down
Stopping laradock_nginx_1            ... done
Stopping laradock_php-fpm_1          ... done
Stopping laradock_phpmyadmin_1       ... done
Stopping laradock_workspace_1        ... done
Stopping laradock_docker-in-docker_1 ... done
Removing laradock_nginx_1            ... done
Removing laradock_php-fpm_1          ... done
Removing laradock_phpmyadmin_1       ... done
Removing laradock_workspace_1        ... done
Removing laradock_mysql_1            ... done
Removing laradock_docker-in-docker_1 ... done
Removing network laradock_frontend           
Removing network laradock_backend            
Removing network laradock_default            
```

MYSQLのデータベースファイル削除
---
コンテナの削除と再作成ではデータベースファイルは再作成されませんのでデータベースファイルを削除します。
コマンドプロンプトの人はrm使えなければエクスプローラーで直接消してもいけました。

```sh
>rm -rf ~/.laradock/data/mysql      
```

my.cnfファイルの編集
---
default_authentication_plugin=mysql_native_passwordをmy.cnfファイルへ追加します。

```config:MyWork\laradock\mysql/my.cnf
[mysqld]
sql-mode="STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"
character-set-server=utf8
default_authentication_plugin=mysql_native_password       ←この設定を追加
```

createdb.sqlファイルの作成と編集
---
MyWork\laradock\mysql\docker-entrypoint-initdb.d配下にcreatedb.sqlファイルを作成します。
同ディレクトリにcreatedb.sql.exampleファイルがあるので.envファイルでやったようにコピーして作成します。

```sh
>cd mysql\docker-entrypoint-initdb.d
>cp createdb.sql.example createdb.sql
```

作成したcreatedb.sqlファイルへユーザーの追加処理の変更を加えます。
"FLUSH PRIVILEGES ;"の前にコマンドを4行追加しています。

```sql:MyWork\laradock\mysql\docker-entrypoint-initdb.d/createdb.sql
# Copy createdb.sql.example to createdb.sql
# then uncomment then set database name and username to create you need databases
#
# example: .env MYSQL_USER=appuser and needed db name is myshop_db
#
#    CREATE DATABASE IF NOT EXISTS `myshop_db` ;
#    GRANT ALL ON `myshop_db`.* TO 'appuser'@'%' ;
#
#
# this sql script will auto run when the mysql container starts and the $DATA_PATH_HOST/mysql not found.
#
# if your $DATA_PATH_HOST/mysql exists and you do not want to delete it, you can run by manual execution:
#
#     docker-compose exec mysql bash
#     mysql -u root -p < /docker-entrypoint-initdb.d/createdb.sql
#

#CREATE DATABASE IF NOT EXISTS `dev_db_1` COLLATE 'utf8_general_ci' ;
#GRANT ALL ON `dev_db_1`.* TO 'default'@'%' ;

#CREATE DATABASE IF NOT EXISTS `dev_db_2` COLLATE 'utf8_general_ci' ;
#GRANT ALL ON `dev_db_2`.* TO 'default'@'%' ;

#CREATE DATABASE IF NOT EXISTS `dev_db_3` COLLATE 'utf8_general_ci' ;
#GRANT ALL ON `dev_db_3`.* TO 'default'@'%' ;

CREATE USER 'default'@'localhost' IDENTIFIED WITH mysql_native_password BY secret;     ←追加
CREATE USER 'default'@'%' IDENTIFIED WITH mysql_native_password BY secret;             ←追加
GRANT ALL PRIVILEGES ON default.* TO 'default'@'localhost' WITH GRANT OPTION;          ←追加
GRANT ALL PRIVILEGES ON default.* TO 'default'@'%' WITH GRANT OPTION;                  ←追加
FLUSH PRIVILEGES ;
```

コンテナの作成と起動
---
Laradockディレクトリに戻ります。
docker-compose upコマンドでコンテナの作成と起動を行います。

```sh
>cd ../../
>docker-compose up -d --force-recreate nginx mysql workspace phpmyadmin
Creating network "laradock_frontend" with driver "bridge"
Creating network "laradock_backend" with driver "bridge"
Creating network "laradock_default" with the default driver
Creating laradock_mysql_1            ... done
Creating laradock_docker-in-docker_1 ... done
Creating laradock_workspace_1        ... done
Creating laradock_phpmyadmin_1       ... done
Creating laradock_php-fpm_1          ... done
Creating laradock_nginx_1            ... done          

>docker-compose ps
指定されたパスが見つかりません。
           Name                          Command               State                    Ports
---------------------------------------------------------------------------------------------------------------
laradock_docker-in-docker_1   dockerd-entrypoint.sh            Up      2375/tcp
laradock_mysql_1              docker-entrypoint.sh mysqld      Up      0.0.0.0:3306->3306/tcp, 33060/tcp
laradock_nginx_1              /bin/bash /opt/startup.sh        Up      0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
laradock_php-fpm_1            docker-php-entrypoint php-fpm    Up      9000/tcp
laradock_phpmyadmin_1         /run.sh supervisord -n -j  ...   Up      0.0.0.0:8080->80/tcp, 9000/tcp
laradock_workspace_1          /sbin/my_init                    Up      0.0.0.0:2222->22/tcp
```

再度WorkSpaceコンテナでphp artisan migrateコマンドを実行します。

```sh
>docker-compose exec --user=laradock workspace bash

>php artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table
```
php artisan migrateコマンドが成功しました。お疲れ様でした！


※2020/1/8追記　
最後の「php artisan migrate」コマンド打ってもエラーが出る場合は、
下記コマンドでartisanコマンドのキャッシュを更新すると上手くいく場合があります。

```sh
php artisan config:cache
```

Laradock及びLaravelの導入にあたって参考にさせて頂いたサイト
---

[Laradock公式サイト](http://laradock.io/)
[Laradockを使ってLaravel 5.5環境を構築する](https://qiita.com/rock619/items/62c2ab2252c405e26479)
[Laravel 5.5 TOC](https://readouble.com/laravel/5.5/ja/)
[【Docker】MySQL8.0系を使う時に発生する問題について](https://blog.websandbag.com/entry/2018/05/17/121730)