Docker Desktop WSL 2 ＋ PhpStormでPHP開発環境を作ってみる

情報が古くなったため、記事を修正してブログに投稿しました。

前編：WSL2、Dockerの設定

https://blog.odaryo.com/2021/08/win-dev_env-with-docker-desktop-1/

後編：PhpStormの設定

https://blog.odaryo.com/2021/08/win-dev_env-with-docker-desktop-2/


# ※ 下記は古い情報となります。

# はじめに

Windowsでの開発環境構築の面倒さやDocker for windowsでのビルドの遅さに嫌気がさし
しばらくLinuxに逃げていましたが、WSL2に興味を惹かれて開発環境を作ってみました。

現在メインに使っているPhpStormでLaravel開発環境を設定する手順についてまとめています。

## 概要

PhpStorm（Intellij IDEA）からWSL2のDockerコンテナ内のPHPをリモートインタープリターで設定し、ついでにXdebug、PHPUnitの設定も行います。

## 環境
- Windows 10 professional
    - バージョン1903（OSビルド 19018.1）
- WSL2：Ubuntu 18.04
- PhpStorm 2019.2.4

# 手順
1. WSL2の有効化
2. Dockerのインストール
3. Dockerの外部アクセス設定
4. Dockerコンテナの起動
5. PhpStorm設定

## １．WSL2の有効化

WSLにUbuntuをインストールして、WSL2に変換します。

※すでにいろいろな情報が出ているのでざっくりと。

① Windows InsiderPreviewのFastリングを導入

② 仮想マシンを有効化

```bash
> Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform
```

③ WSLのバージョンを2に変更

```bash
> wsl --set-version Ubuntu-18.04 2
```

④ バージョン2になったことを確認

```bash
> wsl -l -v
  NAME            STATE           VERSION
* Ubuntu-18.04    Running         2
```

## ２．Dockerのインストール

"Docker Desktop WSL2"をインストールします。

下記docker blogの「Want to give it a go?」に書いてあるとおりに設定します。
https://blog.docker.com/2019/07/5-things-docker-desktop-wsl2-tech-preview/

これまでにWSL2はインストール済みと思いますので、「4.Finally, download the Tech Preview」のリンクからダウンロード、インストールを行ってください。

起動後に、タスクバーのdockerアイコンを右クリックし「WSL 2 Tech Preview」を選択します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536139/f13e7415-9446-afe7-e403-64ecd73a1b2c.png" width="30%">

「Status」タブ内の「Start」ボタンをクリックして起動します。
自動起動の設定が見当たらないため、Windowsの再起動のたびにStartボタンを押す必要があるかもしれません。
![2019-11-22_00h26_29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536139/1735dbdb-be71-a417-707f-b61c75790973.png)

※ このままだとWSL2からの実行にroot権限が必要なため、root以外でも使えるように設定します。

WSL2にログインして下記コマンドを実行しす。

```bash
$ sudo usermod -aG docker your-user
```

## ３．Dockerの外部アクセス設定

WindowsホストからWSL2上のdockerを操作できるように、外部接続の設定を行います。
"Docker Desktop WSL2"のWSL2設定画面のSettingsタブ内に、下記内容を設定してください。
![2019-11-22_00h26_35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536139/a2d6a32d-921e-df2f-d242-ce235eaed704.png)
記載内容はこちらです。

```json
{
  "hosts": [
    "unix:///var/run/docker.sock",
    "tcp://0.0.0.0:2375"
  ]
}
```

dockerを再起動します。

これで、Windows側から```<wsl2のIPアドレス>:2375```でアクセスできるはずです。

※ Docker for Windows で「Expose daemon on tcp://localhost:2375 without TLS」にチェックしていたら別のポートを指定してください。
※ ```localhost:2375```ではアクセスできませんでした。
```.wslconfig```に設定を追加すればWebサーバーの方はアクセス可能ですが、他のプロトコル用では無理？


## ４．Dockerコンテナの起動

今回はDocker内にPHP環境を構築します。  
下記仕様でコンテナを作成しました。

- Nginx
- PHP 7.3
    - Xdebug
    - PHPUnit
- Laravel 6

ソースコードは下記に置いてあります。
https://github.com/odaryo/php_docker_sample.git

適当なディレクトリにクローンしてセットアップします。
ここでは /workspace にプロジェクトを作るものとして説明します。

（以下WSL2内での作業）

```bash
$ cd /workspace
$ git clone https://github.com/odaryo/php_docker_sample.git .
```

Docker起動

```bash
$ cd php_docker_sample
$ docker-compose up -d --build
```

Laravel初期設定

```bash
// コンテナに入る
$ docker-compose exec php-fpm /bin/bash

// 下記はコンテナ内で実行
$ composer install
$ cp .env.example .env
$ php artisan key:generate
$ exit
```

http://localhost:8080 でlaravelのトップ画面が表示されることを確認します。

## ５．PhpStorm設定

### ① パスの設定

Windows領域をマウントしての処理はWSL2でも早くない（むしろWSL1よりも遅い）そうなので、プロジェクトはWSL2上で管理し、Windowsからアクセスするように設定します。

Windowsからは、WSL2のルートディレクトリが下記パスで見えます。
```\\wsl$\ubuntu-18.04\```
IDEにそのまま設定すると```$```が使えないと怒られるため、WSL2へのアクセスパスをネットワークドライブ（ここでは Z:）に設定します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536139/32715b4f-5868-5dd6-02d0-663d59453359.png" width="80%">

今回の例では下記のように対応しています。

WSL2側 → /workspace/php_docker_sample
Win側 → Z:\workspace\php_docker_sample

### ② PHPインタープリターの設定

PhpStormの設定画面からWSL2上のdockerコンテナを指定します。

設定画面を開き、「Build, Execution, Deployment」-「Docker」の内容を編集します。
・「TCP Socket」の「Engin API URL」に、```tcp://<WSL2のIPアドレス>:2375```を設定（localhostだとうまくいきませんでした。）
・「path mapping」にWSL2とWindowsのプロジェクトディレクトリの対応値を記載
・ ステータスが「Connection Successful」となることを確認
![2019-11-22_00h51_14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536139/5f9d61e5-e1cf-c1ea-0acd-8b4f4b9a941b.png)

「Languages & Frameworks」-「PHP」内の「CLI Interpreter」の右側にある「...」を選択します。
![2019-11-22_01h05_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536139/df5a4015-d959-1c6c-5506-e6d8b60c2595.png)

左上の「＋」ボタンを押して「From Docker,....」を選択します。
Server名に先程作成したDockerサーバーを設定し、PHP-FPMのコンテナを選択します。
成功すると「General」欄にPHPのバージョンなどの情報が表示されます。
![2019-11-22_00h47_00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536139/c2c6e149-c22b-f1b0-a99a-e7634a94302a.png)

この状態でOKボタンを押すと、「CLI Interpreter」欄にPHPのバージョンなどが表示されます。
※ 「path mapping」がおかしい場合は手動で修正してください。
![2019-11-22_01h15_26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536139/d9a41e84-398d-3d60-da11-0390fa74afb9.png)

### ③ Xdebugの設定
設定画面から「Languages & Frameworks」-「PHP」-「Debug」を開きます。
「Debug port」にxdebug.confで設定したポート番号を入力します。
![2019-11-22_20h22_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536139/b570a5fb-93c3-6639-ff2a-1c63022aa166.png)

設定画面を閉じ、エディタ右上の「Add Configuration...」より、Xdebug利用設定を行います。
左上の「＋」ボタンから「PHP Remote Debug」を選択します。
![2019-11-22_20h27_00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536139/05a3082a-627a-2390-c2a7-2c4d7e9ba6aa.png)

「Filter debug connection by IDE key」にチェックし、Serverを設定します。
未作成の場合は右側の「...」ボタンから追加してください。
![2019-11-22_20h40_16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536139/89406a7b-a28c-ce25-11a2-9c8e9a87b7b5.png)

PortはWebサーバーのポート（今回は8080）、DebuggerにはXdebugを設定します。
「Use path mapping」にチェックを付けDockerコンテナ内とパスを合わせます。
![2019-11-22_20h30_34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536139/223e283d-f8fe-b908-ace9-c57e07bd6450.png)

OKボタンを押したあと、「Server」「IDE key」を設定します。
![2019-11-22_20h34_00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536139/23d3da32-d370-bb15-16e2-9a9e9926375b.png)

これで設定完了です。
ブレークポイントでデバッグができることを確認します。
![2019-11-22_20h36_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536139/bf2ae648-bba5-7833-ac2d-84ff85925994.png)


※ブレークポイントで止まらない場合はWindows側のFirewallが原因の可能性かもしれません。
ポートを開放するか、Firewallの解除でデバッグできることを確認しました。

### ④ PHPUnitの設定
「Languages & Frameworks」-「PHP」-「Test Frameworks」を開きます。

左上の「＋」ボタンを押し、PHPインタプリタを選択します。
「Path to script」にautoload.phpのパスを、「Default Configuration file」にphpunit.xmlのパスを記載します。
※ 注意点として、パスの入力欄はどちらもDockerコンテナ内のパスを記載してください。
![2019-11-22_01h31_57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536139/2f66635c-4b89-50b3-15ef-be9acc04ecec.png)

設定画面を閉じ、エディタ右上の「Add Configuration...」より、PHPUnit利用設定を行います。

PHPUnitを追加し、
![2019-11-22_01h29_53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536139/cd931d7c-ce3d-d7d9-70a3-90dde3191480.png)

「Defined in the configuration file」を選択します。
![2019-11-22_01h31_22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536139/d3fac096-eacc-ea8f-5dcb-e13a9f277f39.png)

その後、テスト実行ボタンを押して、テストが完了することを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536139/60f698f4-88cf-24c9-187c-c4b0d39fc934.png)


# おまけ

## WSL2のIPアドレスについて

WSL再起動のたびにIPアドレスが変わるため、その都度IPアドレスの変更が必要となります。(2019/11/22現在)

ビルド18495より、C:\Users\<yourUsername>\に.wslconfigを作成し、localhostForwarding=trueを設定するとlocalhostでWSL2にアクセスできるようになりました。
（https://docs.microsoft.com/ja-jp/windows/wsl/release-notes#build-18945）

ブラウザからはlocalhostでアクセスできるようになったのですが、dockerへはつながらない...
ポートの設定でできるようになるかもしれませんが、未調査です。

## Node.jsのインストール先について

コンテナ内のnode.js(yarnやnpm)を実行すると遅いため、node自体はコンテナ外のものを使ったほうが良いと思います。

ですので、WSL2上にインストールしてPhpStormと紐付けます。

Nodeのバージョン管理ツールNVMをインストール
```bash
$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
```

設定が.bashrcに書き込まれるので、更新するためターミナルを閉じて再度開くか、下記コマンドを実行します。

```bash
$ source ~/.bashrc
```

Node.jsのインストール
（※ 執筆時点でのLTS版をインストールしました。）

```bash
$ nvm install 12.13
```

PhpStormの設定は「Languages & Frameworks」-「Node.js and NPM」から行えます。
「Node Interpreter」を選択肢、一番下の「Add...」を選択します。
さらに出てくる選択欄から「Add WSL...」を選択するとWSL上のNode.jsが選べます。
![2019-11-22_01h18_45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536139/7464c004-95df-cce6-41b4-ca2e9740c41a.png)

# 終わりに

さすがにLinuxホストにはビルド速度など敵わないですが、Linuxと遜色ない機能が使えるのは大きいです。

WSL2はまだまだ開発途中ですので、今後のバージョンアップに期待したいです。

今回は"Docker Desktop WSL2"を使ってインストールしましたが、WSL2に直接dockerをインストールしても同じことができるかもしれません。~~（未調査）~~ → 追記しました

# 追記（2019/11/29）

Docker for windowsを削除して、WSL2上にインストールしたDockerから操作可能なことを確認しました。

1. 公式ドキュメントを参考にDockerをインストール
2. ```/etc/docker/daemon.json```を下記内容で作成

```
{                                                                                                   
    "hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2375"],                             
    "experimental": true                                                                }                     
```

- 注意点
    - 上記設定と同様にlocalhostでアクセスできなかったため、WSL2のIPアドレスを指定する必要があります。