vscode↔Docker内PHPでリモートデバッグしたときにハマったこと

Dockerコンテナの中で動くPHPプログラムに、XDebugを使ったリモートデバッグを行う という例は割とよく見かけますが、それでも割とハマったのでハマったところをメモ。

# 構成
* Windows 10 Home(1809 Ver 非Insider Preview)
* Virtual Box(Docker Toolbox)
* PHP 5.5.9
* XDebug 2.2.3
* Visual Studio Code 1.32.3

# 気をつけるべきところ
## XDebugでのデバッグにおいて気をつけるべきところ(覚えておくべきところ)

* XDebugでデバッグをするとき、Visual Studio Codeは**サーバ側**、PHPインタプリタは**クライアント側**になる(PHPインタプリタからVisual Studio Codeにアクセスする)
    * なので、DockerコンテナのEXPOSEなどは不要。むしろそれをするとかえって厄介なことになることがある)
* vscode上の`launch.json`で指定する`pathMappings`で指定するDockerコンテナ側のディレクトリパスは、**ルートディレクトリからのパス**となる。HTTPサーバ上で見えているディレクトリ などではない。
* ワークスペースを作成していても、Windows PC側のフォルダパスは、基本的に`${workspaceFolder}`でOK。
  
## Dockerを使う上で気をつけるべきところ

* DockerコンテナからDocker Toolboxを動かしているPC(Windows PC)を見るときと、Windows PCからDockerコンテナを見るときのIPアドレスを覚えておく
    * Windows PC→Dockerコンテナの場合、IPアドレスは、**ホストOS(Virtual Boxで走っているOS)の`ifconfig`で取得できる`eth1`の値**(Virtual Boxの設定＞ネットワーク＞アダプター2で選択しているホストオンリーアダプターと同じネットワークのアドレスになるはず)
    * Dockerコンテナ→Windows PCの場合、**ホストOSの`ip r`で取得できる値**(先頭行に`default via ××× dev eth0`などと出力されるので、その×××の値)

# 準備

## Dockerコンテナ側の準備

Dockerコンテナ側の準備は

* XDebugをインストールすること
* XDebug.iniに設定をすること
* デバッグ対象のPHPファイルを正しく配置すること

となる。php5の場合は、`apt-get install php5-xdebug -y`しておくこと(7以降の場合は適宜読み替えてください)。

### XDebug.ini

Dockerコンテナ→Windows PCのIPアドレスは、今見ている限り変わってないので、build-argsなどで設定したりせずとも決め打ちで良いと思われます。

```ini:xdebug.ini
zend_extension=xdebug.so

[XDebug]
xdebug.dump_undefined = 1
xdebug.remote_enable = 1
xdebug.remote_host=10.0.2.2
xdebug.remote_port=9000
xdebug.remote_handler=dbgp
xdebug.remote_mode=req
xdebug.remote_autostart = 1
xdebug.remote_log=/var/log/xdebug.log
```

## Visual Studio Code側の準備

* PHP Debugの拡張をインストールしておくこと
* launch.jsonを正しく設定すること
* 該当PHPファイルを開き、ブレークポイントを仕掛けておくこと

```json:launch.json
・・・
    {
      "name": "XDebug on Docker",
      "type": "php",
      "request": "launch",
      "port": 9000,
      "pathMappings": {
        "/app/*** プロジェクトフォルダまでのパス ***": "${workspaceFolder}"
      }
    },
・・・
```

## Dockerfileの注意点

とくになし。強いて言うなら**ポート9000をEXPOSEしたり、`docker run`で`-p 9000:9000`などとしたりしないこと！(これをしていたせいでハマった可能性大)**

# いざ実行

1. 最初に、Visual Studio Codeで**デバッグの開始**を行う(PHPインタプリタの接続待ち)
2. PHPファイルの任意の箇所にブレークポイントを設置する
3. DockerコンテナのPHPファイルを、Windows PC側で表示する
4. Enjoy.

# 感想

* Dockerコンテナ↔外側のPCとのアクセスは確認する方法がそれぞれ違うので気をつけること。
 * 可能なら事前に外側のPCに`php -S 127.0.0.1:8080`あたりで作ったサーバにDockerコンテナからアクセスしてみるなど、なんらかの形で導通確認をしておくとよい(pingだけでは実はループバックしてるのかDockerのホストOSに飛んでるだけなのか、ちゃんと外側のPCに飛んでいるのか区別が付きづらい)。
* それでもつながらない ということは割とよくあるので、**どういう仕組みでつながっているのか**を理解しておくことは重要。
* リモートデバッグは動き始めれば快適(サーバが物理的に離れてればまた感覚が変わってきそう)。print()デバッグとかerror_log()デバッグでお茶を濁そうとしたりせず、素直に使いましょう。

# 参考にしたもの
* [\[PHP\] Xdebug のリモートデバッグ、理解していますか？ \- Qiita](https://qiita.com/castaneai/items/d5fdf577a348012ed8af)
* [Docker上のPHPをxdebugでVisualStudioCodeからデバッグする設定 \- Qiita](https://qiita.com/hiro-tarosuke/items/adcc382ca98dfb89401b)
* [php \- VSCodeでのXDebugとの連携でホストを指定しなくてもいい理由 \- スタック・オーバーフロー](https://ja.stackoverflow.com/questions/36374/vscode%E3%81%A7%E3%81%AExdebug%E3%81%A8%E3%81%AE%E9%80%A3%E6%90%BA%E3%81%A7%E3%83%9B%E3%82%B9%E3%83%88%E3%82%92%E6%8C%87%E5%AE%9A%E3%81%97%E3%81%AA%E3%81%8F%E3%81%A6%E3%82%82%E3%81%84%E3%81%84%E7%90%86%E7%94%B1)
* [Windows \+ VirtualBox \+ Docker で動作しているコンテナからホスト OS へのアクセス \- takaya030の備忘録](http://takaya030.hatenablog.com/entry/2016/10/29/000647)