【Docker】Laravelの開発環境を最速で作ってみたかった【Windows10】

## 最初に
以前[VagrantでLaravelの環境構築](https://qiita.com/mashirou_yuguchi/items/915c01dd75eb87630f19)を書いた人です。

Vagrantは個人で開発するには安いコストで済むのでサクサクやれるのですが、チーム開発だとやっぱりPCごとに色々と差異が出やすいから、もっとお手軽に開発環境を一括で整えたいって方には[Docker](https://www.docker.com/)が便利。

そんな中、[Laradock](https://laradock.io/)というこの世のすべて（すべてとは言っていない）をここに集めたくらいには集まっている素敵ツールがあります。

そこで超最短で作れるLaradock用いたDockerでのLaravel開発環境構築をしていきます。

ちなみに僕は最速で1時間弱でした。理解が足らずで20分くらい無駄足を踏んだことは秘密にしておいてください。
~~n番煎じなのはご愛嬌ということでなにとぞ~~

### 承前
タイトルにもありますが今回はWindows10前提で構築を進めています。
Windows7やWindows10 Home版をお使いの方はDockertoolboxを使用する必要がありますが、今回はそちらを使わずDocker Community Editionを用いるため、今回の構築対象外となります。予めご了承ください。
あとネットワーク通信が不可能な環境の方もご遠慮ください。
（昨今そんなレベルの環境で開発されることはWeb系ではほぼないとは思いたい限りではありますが。。）

Mac版の方は令和が終わるころにエントリーを作ります。（来世）

## 準備
WindowsでDockerを使う場合、Hyper-Vを設定して仮想環境の設定を可にする必要があります。
`control panel -> [プログラムと機能] -> [Windowsの機能の有効かまたは無効化] `
直下にHyper-Vを設定する項目があるのですべてチェックを入れてください。
完了後、再起動して適応しましょう。

※この設定を行うとVagrant等のVMツールが競合して使えなくなります。

## Dockerを導入する

なにはなくともDockerをインストールします。特に設定をするなどは必要はないので推奨設定のままで作成しましょう。
https://hub.docker.com/editions/community/docker-ce-desktop-windows

サクッとインストールしていただいてツールバーにクジラが潮を出したまま停止しているアイコンがでてくるまで待ちましょう。

## laradockを導入する

https://laradock.io/
実は公式のQuick Over Viewにもうすでに、「すぐに動かそうぜ！」みたいな記述がありまして。
ただし今回の目的やりたい方法とは少し違っていたため今回は[1]と[2]の操作のみを行います。

~~~
git clone https://github.com/Laradock/laradock.git
cd laradock
cp env-example .env
~~~

コピーして早速起動！と言いたいところですが、Dockerは起動しながら修正などを繰り返すと、それだけで1日終わるくらいには長丁場になります。（特にLaradockにおいては確実に。）
そのため、一筆で構築できるように準備を進めていきます。

その前に注意点（主に僕が詰まった点）の説明をば。（読み物程度の気持ちで流してください）
### やらかし１：APP_CODE_PATH_HOSTを読み間違える
高校の時の現代文は10段階評価中7か8をほとんど取っていたのに、
中間テストでガン寝して取った至高の0点テストによって評価点4を獲得してしまった並のひどいやらかし具合です。
<details><summary>思ったより長かったので折りたたみ</summary><div>
もはや書いてある通りのはずなのに
「ああ、ここがLaravelの配置する場所なんだなぁ」
などと供述し沼にハマりました。

APP_CODE_PATH_HOSTは読み込む場所ではなく場所として置く場所、その最上位であるということです。
畳みかけるように言えばすぐ下の行にある**APP_CODE_PATH_CONTAINER**などはコンテナを作成したとき、HOSTがどの直下になるかを指定する場所なのです。
要はWorking_Directoryですね。

/var/wwwと書いてある時点で気づけよくらいなのですが、ここで30分も引っかかりました。奇跡ですね。
ちなみに何も指定しないとlaradockが配置してあるとディレクトリ層と同じ場所になります。

なので実際にコンテナに入ると以下の感じになります

~~~
PS C:\docker\laradock> docker-compose exec workspace /bin/bash
WARNING: The APPLICATION variable is not set. Defaulting to a blank string.
root@0cf4b894fa02:/var/www# ll
total 4
drwxrwxrwx 2 root root 4096 May 10 07:20 ./
drwxr-xr-x 1 root root 4096 Apr 16 03:42 ../
drwxrwxrwx 2 root root    0 Mar 15 03:57 dynamodb/
drwxrwxrwx 2 root root    0 Mar 14 06:26 dynamodb-data/
drwxrwxrwx 2 root root    0 Mar 15 10:00 laradock/
drwxrwxrwx 2 root root    0 Apr  9 08:38 minio/
~~~
ここでAPP_CODE_PATH_HOSTで指定をするとその直下のディレクトリがワーキングディレクトリになるということになります。
おそらく何も考えずに指定なしでコンテナを立ち上げて中身を見れば構造が理解できたような気もしますが現実は非情。
無駄な時間を消費してしまいました。:innocent:
</div></details>

### やらかし２：nginx(apache2)に設定するのを忘れる
恥の多い人生を歩んできましたが、
これはドレスコードが必要なフランス料理店で「フォークとナイフは外側から」レベルの常識を忘れる程度のやらかし具合。
**嘘です。やったこと無いから気が付かなかっただけです。**
<details><summary>思ったより長かったので折りたたみ</summary><div>
普段からlinux環境に触っている人なら忘れることはないでしょう。
そう、サーバ環境の設定でconfを弄る必要があるのです。
が、その前提をわすれてdefault.confの**/var/www/public**を見に行っていて404で動かないことを5分くらい唸っていました。
なんでだろうと思ってふとhistoryに残っている**dockeer-compose nginx mysql redis minio**によって某ラノベの有名台詞を綴ることになりました。
~~**「思い……だした……！！」**~~
あたりまえ程度の知識にはなってしまいますが、ここでしっかりとファイルの設定をしてあげることで環境構築時にストレートに構築ができるようになります。

なんならここでファイルを作ってしまえば本番構築時にだいたい流用もできると優れもの。ここで練習できるのはお得以外の何物ではないですね。
ちなみにapp.confやlaravel.conf、symfony.confと複数のexampleファイルがありますが、今回はLaravelなのでlaravel.confをコピーしてお好みのファイル名にしてあげましょう。

~~~
cp laravel.conf.example hogehoge.conf
~~~
どんな違いがあるかって？
server_nameとかrootを見てみればわかるかと思いますがlaravelやらsymfonyやらと特有の記載がありますね？そのまま自分のプロジェクト名に置き換えれば疎通できるようになります。便利ですね。

apache2には残念ながら汎用型のexampleファイルしかありませんので頑張って作りましょう。
大丈夫大丈夫~~日本語で書かれたサイトなら設定の仕方がどこかしらに載せてくれているはずなので（丸投げ）~~

（海外の方ってNginxの方が主流なのかしら。周囲の人はみんなApache勢だから傾向が分からない……）
</div></details>

## 環境設定
やらかしを見たことによって**†心理的安全性†**を得たあなたはもう大丈夫、失敗は怖くないのでサクサク設定していこう。
主にlaravelを動かしたいだけならこの状態でただ起動をすれば良いのだけれど、
その場合は404 NotFoundを眺め続けることになるのでそうならないために設定していく。

主に編集対象は以下
`.env`
`php-fpm/laravel.ini`
`nginx/sites`

```terminal:.env
#laradockと同階層に適当につけたディレクトリ名を指定してください
#だからといって日本語ディレクトリとかつけたらギルティ
#APP_CODE_PATH_HOST=../
APP_CODE_PATH_HOST=../your_working_directory

#自分が使いたいphpのバージョンを指定してください（こだわりなければ最新のを使えばいいと思う）
PHP_VERSION=7.3

#Nginxは初期portが8000になっているが他のツールを使うとなったとき被りやすいので適宜変更
NGINX_HOST_HTTP_PORT=8001

#mysqlは初期の状態だとlatest、つまり8系がインストールされる。
#パスワードの認証方式などが変わって面倒になるので以下の通りに変更していく必要がある。
#DB名とかユーザパスワードは好きに設定してください。
MYSQL_VERSION=5.7
MYSQL_TIMEZONE="Asia/Tokyo"
MYSQL_DATABASE=default
MYSQL_USER=default
MYSQL_PASSWORD=secret
MYSQL_PORT=3307
```
※mysql8.0を使いたい方は[こちら](https://qiita.com/ucan-lab/items/3ae911b7e13287a5b917)から解消していってください。

```terminal:php-fpm/laravel.ini
#初期の設定から以下のように変更
date.timezone=Asia/Tokyo
memory_limit = 1G
upload_max_filesize = 512M
post_max_size = 512M
```
さらっと書いて行きましたが一応説明をば。
`timezone`はUTCだと何かと時間ズレなどで正常でない動きがありえますので現地に変えました。
`memory_limit`は処理の上限値を1GBと基本的には落ちないであろう数字に設定しました。
動画などを取り扱わない限り問題無い……はず。
`upload_max_filesize`はファイルをアップロードする最大容量です。
`input type`でファイル形式を指定されて画像のアップロードをされている方には縁深いかもわからないですね。（メールとかもそう）
`post_max_size`は`upload_max_filesize`と同様のものです。`form`で`method`を`post`にした人には縁深いところ。

ちなみに
`memory_limit` → `upload_max_filesize` → `post_max_size`の順で最大容量を指定してください。`memory_limit`以上を選択しても特に効果はありません。

ここで、サーバで作業されたかたはお気づきになっているとは思いますが、この変更はなぜ`php.ini`で編集しないのかということを。
答えは`php-fpm/Dockerfile`から`laravel.ini`で検索ゥ！

<details><summary>長いので折りたたみ</summary><div>

```dockerfile:php-fpm/Dockerfile
//~~~~~
// 省略
//~~~~~
#
#--------------------------------------------------------------------------
# Final Touch
#--------------------------------------------------------------------------
#

COPY ./laravel.ini /usr/local/etc/php/conf.d
COPY ./xlaravel.pool.conf /usr/local/etc/php-fpm.d/

//~~~~~
// 省略
//~~~~~
```
こんな書き方をしているのでだいたいわかったと思いますが、`php.ini`を動かすために必要な設定ファイルの`conf.d/`が`laravel.ini`の正体になります。

関係値、というかしきい値の当てはめの上下関係が`conf.d/`が優先されるためです。（キャッシュ的な考えだとしっくり来るかも……？）
そのため、基本的にはcond.d = laravel.iniを編集しておくと反映されるようになります。
</div></details>

```terminal:nginx/sites
#複製してください
cp laravel.conf.example project.conf
```

```terminal:nginx/sites/project.conf
#以下部分を変更
server_name myproject.test;
root /var/www/myproject/public;
```
このmyprojectは`composer create-project --prefer-dist laravel/laravel 5.* myproject`の部分と同一にすると一撃です。
だからといって謎のスペースを開けたりするとおかしくなるのでハイフンなりアンダーバーなりにしておいてください。

## Docker起動
ここまで来たらようやくDockerを起動するところまで来ました。1時間ちょっとで終わったのは本当なのかと疑われるかと思いますが~~自分自身が1番不思議に思っています。~~事実です。

laradock直下のコンソールでいざ起動

```terminal:./laradock/
docker-compose up -d nginx mysql
```

ゆっくりと起動を待っている間、最後の設定をします。
最後に`hosts`の設定です。です。

```terminal:.\hosts
#Windowsならこの直下にたいていあります。管理者権限でメモ帳から開きましょう
C:\Windows\System32\drivers\etc\

#以下のように追記して保存
127.0.0.1 myproject.test
```
起動できたら`nginx`で設定したserver_nameの`myproject.test`にアクセスしてみましょう。
welcomページが表示されたら導入完了です。

お疲れ様でした。

## 感想
文字だけで全部説明したけど普通に画像使えば？ってくらいのところを文章で説明しました。アホですね。
7割くらいふざけて書いています。
が、実際に自分が仕事で環境構築したときと初期環境と同等のものが作れているはずです。
Laradockの管理が想像以上に面倒くさくぎて自前で作り直したいけど気力が沸かないのでどなたか気力をください。