PHP on Laradock w/ Visual Studio Code(VS Code)でデバッグ環境 (特にon Mac)

Laravelの開発環境は、Laradockでサクサクっと作れるようになったけど...

- [Laradock on macでLaravelの開発環境をサクッと整備 - Qiita](http://qiita.com/yamazaki/items/d8b583a0fee70cadfc7b)

実際に開発を進めていくとデバッグ作業は当然つきもの。

過去、もう10年以上前だけれど、SIerにいた時は、VB6やVB.NET, Javaで有償のIDEを利用するのが当たり前だったから、デバックといえばステップ実行で処理途中の変数の中身を見たりなんてのは普通の開発環境だった。

でも、ウェブ業界に来て、開発はテキストエディタ、しかも、デバックの際はコードの途中に `print` や `echo` などを書いて地道に調べていく... なんともアナログな環境に驚いた。

昔話はまぁ、そんな感じだけど、最近はテキストエディタも高機能化していて、意外と手軽に有償のIDEと同じようなデバッグ環境を作れるようなので、今回は、それに挑戦した時のメモ。

# Laradockの設定

まずは、公式のページと、あまたあるウェブの情報を多数拾って読んだけれど、今回エディタで選択したVisual Studio CodeとLaradockのドンピチャな設定例が見つからなくて少しテコづった。総合的に情報を把握して、いくらか設定の試行錯誤をして成功したので、同じ環境の人の参考にはなるんじゃないかと。(全然、難しい内容じゃないので、慣れている人は手順なんていらねーって話かもしれないがw)

20,30のページは見たけれど、最終的に参考になったのは、以下、公式と、どこぞの誰かのブログ。

- [Documentation # Install-xDebug - Laradock](http://laradock.io/documentation/#install-xdebug)
- [開発環境 : Laradockで動作するPHPアプリをリモートデバッグ | DN-Web64](http://www.dn-web64.com/archives/web/laradock_xdebug/)

Laradockも当然デバック環境を意識して作り込みされているので、設定を少し変えるだけでエディタのデバッグと連携することができるようになっている。

## Xdebugの有効化

ということで、まずは、以下の.envの設定でXdebugを有効にする。

```ini:$LARADOCK_ROOT/.env
WORKSPACE_INSTALL_XDEBUG=true
PHP_FPM_INSTALL_XDEBUG=true
```

.envファイルの最後の方には、以下のような設定もあり、エディタによっては必要になるかもしれないので把握はしておくと良いかも。

```ini:$LARADOCK_ROOT/.env
DOCKER_HOST_IP=10.0.75.1
PHP_IDE_CONFIG=serverName=laradock
```

## Xdebugの設定

Xdebugの設定も必要で、対象ファイルが2つある。

- $LARADOCK_ROOT/php-fpm/xdebug.ini
- $LARADOCK_ROOT/workspace/xdebug.ini

```$LARADOCK_ROOT/*/xdebug.ini
xdebug.remote_autostart=1
xdebug.remote_enable=1
xdebug.remote_connect_back=0
xdebug.cli_color=1

; Mac特有の設定
; xdebug.remote_host=dockerhost
xdebug.remote_host=docker.for.mac.localhost
```

上記最後のデバック情報を戻すホストマシンのIPが曲者で、WindowsとMacでDockerのネットワーク構成が異なるため、xdebug.iniの設定も違いがあるので、要注意。

色々設定を変えてみて試したけれど上手くいかず、一晩寝かせてGoogle検索して辿り着いた以下のサイトからヒントを得て、ポインタの公式サイトを見てみたら答えが書いてあった。

- [Docker for Mac上のコンテナから、Mac上のアプリケーションに簡単に接続する方法 - Qiita](http://qiita.com/Asayu123/items/ccfe4ccfc417ce57f445)
- [Networking features in Docker for Mac | Docker Documentation](https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds)

公式サイトに、まんま書かれていた。

> I want to connect from a container to a service on the host
> The Mac has a changing IP address (or none if you have no network access). From 17.06 onwards our recommendation is to connect to the special Mac-only DNS name docker.for.mac.localhost which will resolve to the internal IP address used by the host.

Dockerのバージョン17.06以降、コンテナからホストへアクセスする際は、「docker.for.mac.localhost」で名前解決してIPを特定することを推奨する、だそうな。

ということで、Xdebugのレスポンスは、docker.for.mac.localhostを指定。
**これが一番ハマった。**

---
追記: Aug. 29, 2017

コンテナから見たホストマシンのIPに関して、以下に、少し詳しく書かれていた。

- [Docker for Mac 上のコンテナに対して、PhpStorm + xdebug でリモートデバッグ # なぜエイリアスを追加しないといけないのか？ - Qiita](http://qiita.com/kunit/items/52518cb1460d3deb6034#%E3%81%AA%E3%81%9C%E3%82%A8%E3%82%A4%E3%83%AA%E3%82%A2%E3%82%B9%E3%82%92%E8%BF%BD%E5%8A%A0%E3%81%97%E3%81%AA%E3%81%84%E3%81%A8%E3%81%84%E3%81%91%E3%81%AA%E3%81%84%E3%81%AE%E3%81%8B)

が、情報が少し古いと思われる。今は、「任意のIPアドレスエイリアスをMac(Dockerホスト)のループバックアドレスに割り当てる」必要ななく、docker.for.mac.localhostで解決。

---

## コンテナの再構築

以上、設定変更だけでなく、Xdebugの追加インストールなどもあるため、変更を反映するにはコンテナの再構築が必要なので、以下のコマンドを実行。

```bash
docker-compose build workspace php-fpm
```

もしくは、以下のコマンドでプロセス立ち上げると同時にビルド実行。

```bash
docker-compose up -d --build nginx mysql
```

# Visual Studio Codeの設定

デバッグの拡張はいくつかあるようだけど、以下が一番有名そうなので、これをインストール

- [PHP Debug - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=felixfbecker.php-debug)

で、VS Codeのデバッグで設定ボタンをクリックするか、ソースファイルのルートディレクトリに、`.vscode/launch.json`を作成して、以下のように記述。

```json:$LARAVEL_PROJECT/.vscode/launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Listen for XDebug",
            "type": "php",
            "request": "launch",
            "serverSourceRoot": "/var/www/laravel",
            "localSourceRoot": "${workspaceRoot}",
            "log": true,
            "port": 9000
        }
    ]
}
```

`serverSourceRoot`は、実際にコンテナ内に配置しているプロジェクトのディレクトリを指定。
`localSourceRoot`は、VS Codeで開くディレクトリのどこが上記の`serverSourceRoot`と同じ階層となるのかを指定する部分なので、VS Codeで開くディレクトとイコールであれば、`${workspaceRoot}`で良い。

以上