Windows 10でDocker + Laravel環境構築

# この記事について
WindowsにDockerをインストールしてLaravelの開発環境を作ろうとしたら
色々とハマる箇所があったので、備忘録として構築手順をざっくりまとめました。
構築にはDocker for WindowsとLaradockを使用しています。

## 環境
###ホスト側
Windows 10 Pro
Node.js
Git For Windows(Git Bash)

###Dockerコンテナ側
Laravel(5.5)
nginx
PostgreSQL

# 目次
- [Hyper-Vの有効化](#hyper-vの有効化)
- [Docker for Windowsのインストール](#docker-for-windowsのインストール)
- [LaradockでDockerコンテナ作成](#laradockでdockerコンテナ作成)
- [Laravelプロジェクト作成](#laravelプロジェクト作成)
- [PostgreSQLの設定](#postgresqlの設定)
- [参考文献](#参考文献)

# Hyper-Vの有効化
WindowsにDocker環境を構築するには、何かしらの仮想化ソフトウェアをインストールしておく必要があります。
Windows 10 ProにはHyper-Vというものが標準で搭載されていますので、今回はそれを使用します。
(Windows 10 Homeには搭載されていないのでお気をつけください。)

[コントロールパネル] → [プログラム] → [Windowsの機能の有効化または無効化]を開きます。
<img width="343" alt="Hyper-V有効化.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173272/b0017909-3312-c6ee-7dec-5bce008162f8.jpeg">
Hyper-Vにチェックを入れて閉じます。もし再起動を促されたら実施してください。

## ちなみに
Hyper-V以外にも、VirtualBoxという仮想化ソフトウェアを使用してもDockerの環境構築は可能です。
しかしこちらはデフォルトの設定ではシンボリックリンクが使えないなどの制約があり、
若干手こずる可能性がありますので個人的にはHyper-Vの使用をおすすめします。

# Docker for Windowsのインストール
[Dockerの公式サイト](https://docs.docker.com/docker-for-windows/install/)から、Dockerのインストーラをダウンロードします。
[Download from Docker Hub]をクリックします。
<img width="648" alt="dockerHub.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173272/9e93cbf9-7e14-9a2c-c8e4-60359eb879bf.jpeg">

Dockerにサインインします。
アカウントを持ってなかったら[Sign Up]のリンクから作成します。
<img width="419" alt="dockerサインイン.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173272/befcd802-c965-115d-27ce-c24fc8fbd91e.jpeg">

サインインして以下の画面が表示されたら[Download Docker Desktop for Windows]のリンクからインストーラをダウンロードします。
<img width="613" alt="dockerダウンロード.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173272/15552f13-cbd5-943d-2a84-babf530b9757.jpeg">

ファイルのダウンロードが完了したら実行します。
インストールの設定はデフォルトで良いです。
(もしDockerコンテナのOSをWindowsにしたい場合は、[Use Windows containers instead of Linux containers]にチェックを入れてください。)
<img width="527" alt="install.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173272/2d481a46-0255-4b84-83ea-7a5ac5dd2870.jpeg">

インストール後、Windowsの通知にDocker Desktop is running.と表示されます。
![running.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173272/2ace3cc5-065f-2356-44af-8ab39aa1ec0c.png)

デスクトップにDockerのショートカットが作成されているはずなので、起動します。
タスクバーにDockerのアイコンが表示されたらしばらく待ちます。
![タスクバー.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173272/837be4bc-b0bf-177a-cc70-2b38c6d1aba4.jpeg)

Welcomeウィンドウが表示されたら起動完了です。
<img width="262" alt="welcome.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173272/f91b8c96-9841-31a4-0d6a-35cb6922a0dd.jpeg">



## 設定変更
Dockerのアイコンを右クリック→[Settings]からDockerの設定画面を開きます。
そこから[Shared Drive]のタブを開きます。
Dockerコンテナ-ホスト間でファイルを共有するドライブを指定してください。
<img width="622" alt="shareddrive.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173272/c459bdce-0707-6213-1e04-b090f53e6395.jpeg">

設定したら[Apply]をクリックして設定を適用してください。
以上でDockerのインストールは完了です。

### Firewall detectedエラーが発生した場合
PC内のウィルス対策ソフトの設定によっては、Dockerの設定変更時にFirewall detectedエラーが発生するようです。
その場合、WindowsのPowerShellを管理者権限で起動し、以下のコマンドを実行してください。

```powershell
Set-NetConnectionProfile -interfacealias "vEthernet (DockerNAT)" -NetworkCategory Private
```

これで解決しなければ、「ポート445のTCP通信の許可」「IPアドレス10.0.75.1からの接続の許可」
あたりをファイアウォールに設定します。

#LaradockでDockerコンテナ作成
Git Bashを起動します。
適当な作業フォルダを作成し、そこに移動します。
(今回はC:\workspace\laradock-test\ とします)

```sh
>cd /c/workspace/laradock-test/
```

GitHubからLaradockをダウンロードします。

```sh
>git clone https://github.com/laradock/laradock.git
```
ダウンロードが完了したらlaradockフォルダに移動します。

```sh
>cd laradock
```

設定ファイルを作成します。
(env-exampleをコピーして .env というファイル名で作成します)

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

Dockerコンテナを起動します。
(このコマンドは初回実行時のみ、Dockerコンテナの作成と起動を行うため、時間がかかります)

```sh
>docker-compose up -d nginx postgres workspace
```

以下のような表示が出たらコンテナ起動完了です。

```sh
Creating laradock_postgres_1         ... done
Creating laradock_docker-in-docker_1 ... done
Creating laradock_workspace_1        ... done
Creating laradock_php-fpm_1          ... done
Creating laradock_nginx_1            ... done
```

念の為、以下のコマンドでコンテナの起動状態を確認します。
(何故か最初に「指定されたパスが見つかりません。」と表示されますが、無視して良いです。

```sh
>docker-compose ps
指定されたパスが見つかりません。
           Name                          Command              State                     Ports
---------------------------------------------------------------------------------------------------------------
laradock_docker-in-docker_1   dockerd-entrypoint.sh           Up       2375/tcp, 2376/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_postgres_1           docker-entrypoint.sh postgres   Exit 1
laradock_workspace_1          /sbin/my_init                   Up       0.0.0.0:2222->22/tcp
```
StateがUpになっているアプリケーションは正常に動作しています。
(この時点ではまだ正しい設定をしていないため、PostgreSQLのみ起動に失敗します)

ちなみに、この時点でコンテナ内でnginxが起動しているはずなので、
ブラウザで[localhost](http://localhost/)にアクセスするとnginxの404 Not Foundエラーが表示されます。
<img width="228" alt="404.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173272/c5676c71-370b-b07f-453c-bf2095f8e9a7.jpeg">

#Laravelプロジェクト作成

コンテナが起動している状態で以下のコマンドを実行し、コンテナに接続します。
(コンテナ内の/var/www がカレントディレクトリになります)

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

Laravelプロジェクトを作成します。
プロジェクト名はここではlaravel-testとします。
Laravelのバージョンはここでは5.5系としますが、適宜変えてください。

```sh
>composer create-project --prefer-dist laravel/laravel laravel-test "5.5.*" 
```
プロジェクトの作成が完了すると、laravel-testディレクトリ以下に諸々のファイルが作られます。

```sh
>ls laravel-test/
app  artisan  bootstrap  composer.json  composer.lock  config  database  package.json  phpunit.xml  public  readme.md  resources  routes  server.php  storage  tests  vendor  webpack.mix.js
```

一旦コンテナから抜けます。

```sh
exit
```

laradockディレクトリ内の.envファイルを開き、以下の通りに書き換えます。

```sh
# Point to the path of your applications code on your host
# APP_CODE_PATH_HOST=../ #この行を消す
APP_CODE_PATH_HOST=../laravel-test/ #この行を足す(laravel-testのところはプロジェクト名)
```

書き換えたらファイルを保存して一旦dockerコンテナを再起動します。

```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

>docker-compose up -d nginx postgres workspace
```

既にdockerコンテナ内でlaravelが実行されているため、ここで[localhost](http://localhost/)にアクセスすると
Laravelのデフォルトページが表示されます。

<img width="470" alt="laravel.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173272/673ffbdd-2295-21e2-327c-4a7e49c02660.jpeg">

これでLaravelプロジェクトの作成は完了です。

#PostgreSQLの設定
laradockの.envを開き、280行目あたりのPOSTGRESの接続情報の設定を好きなように書き換えます。

```sh
### POSTGRES ##############################################

POSTGRES_DB=test_db
POSTGRES_USER=test_user
POSTGRES_PASSWORD=testtesttest
POSTGRES_PORT=54320
POSTGRES_ENTRYPOINT_INITDB=./postgres/docker-entrypoint-initdb.d #この行は変更しなくてよい
```

また、ファイルの最終行に以下の１行を追加します。

```sh
DB_HOST=postgres
```

次に、以下のディレクトリ下の４つのシェルファイルの改行コードをCRLFからLFに変更します。

```sh
>cd /laradock/postgres/docker-entrypoint-initdb.d
>ls 
init_confluence_db.sh  init_gitlab_db.sh  init_jupyterhub_db.sh  init_sonarqube_db.sh
```

次に、作成したLaravelのプロジェクト(ここではlaravel-test)ディレクトリ直下にある.envを編集します。
先程指定した接続設定に合わせて書き換えます。

```sh
DB_CONNECTION=pgsql
DB_HOST=postgres
DB_PORT=54320
DB_DATABASE=test_db
DB_USERNAME=test_user
DB_PASSWORD=testtesttest
```



そしてコンテナを再起動します。

```sh
>docker-compose stop
>docker-compose up -d nginx postgres workspace
```

コンテナの状態を確認。

```sh
>docker-compose ps
指定されたパスが見つかりません。
           Name                          Command              State                     Ports
---------------------------------------------------------------------------------------------------------------
laradock_docker-in-docker_1   dockerd-entrypoint.sh           Up       2375/tcp, 2376/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_postgres_1           docker-entrypoint.sh postgres   Up      0.0.0.0:54320->5432/tcp
laradock_workspace_1          /sbin/my_init                   Up       0.0.0.0:2222->22/tcp
```

postgresのステータスがUPになっていれば完了。

#参考文献

- [Docker for Windowsをインストール](https://ops.jig-saw.com/techblog/docker-for-windows-install/)
- [Get started with Docker for Windows | Docker Documentation](https://docs.docker.com/docker-for-windows/#firewall-rules-for-shared-drives)
- [DockerのShared Driveがノートンのファイアウォールに引っかからないようにする](https://gfonius.net/blog/docker-norton/)
- [Docker for WIndows の導入でハマった点](https://sfbit.co.jp/%E6%8A%80%E8%A1%93/docker-for-windows-%E3%81%AE%E5%B0%8E%E5%85%A5%E3%81%A7%E3%83%8F%E3%83%9E%E3%81%A3%E3%81%9F%E7%82%B9/)
- [Windows10でLaradockを使ってLaravel 5.5環境を作る - Qiita](https://qiita.com/sket88/items/4de708ce394179c61d8a)
- [LaravelでPostgreSQLを使うための設定メモ - Qiita](https://qiita.com/aminevsky/items/52f56546f081c52b79ed)

また、本記事ではVue.jsについては特に言及していませんが、Laravelプロジェクトに
Vue.jsとVuetifyを導入する際に以下の記事を参考にしました。

- [Laravel + Vueの導入からコンポーネント作成まで - Qiita](https://qiita.com/masa08/items/0abe8c93ac75ef8ef98b) 
- [Vue成長日記 #3 ~VuetifyをLaravelに入れる~](https://oversealife.work/2019/09/08/vuetify-laravel/)