Docker上のPHPをXDebugとPHPStormを使いデバッグ

Docker上のPHPアプリを「XDebug」と「PhpStorm」を利用してリモートデバッグしてみます。なお、Dockerコンテナは「Laradock」を利用して立ち上げています。

LaradockでXDebugを有効化

laradock/.env の設定を以下のようにします。

WORKSPACE_INSTALL_XDEBUG=true
 
PHP_FPM_INSTALL_XDEBUG=true
 
DOCKER_HOST_IP=192.168.11.10

laradock/.env は、laradock/docker-compose.yml にて利用されます。

DOCKER_HOST_IP は、Dockerコンテナから見える ローカルマシンのIPアドレス です。ホストマシン上で ifconfig などで確認して設定します。

XDebugの設定調整(不備あり)

  • laradock/workspace/xdebug.ini
  • laradock/php-fpm/xdebug.ini

上記ファイルの設定を以下のようにします。
(注意:後述しますが、下記設定には不備があります。)

- xdebug.remote_autostart=0
+ xdebug.remote_autostart=1
- xdebug.remote_enable=0
+ xdebug.remote_enable=1
- xdebug.remote_connect_back=0
+ xdebug.remote_connect_back=1
- xdebug.cli_color=0
+ xdebug.cli_color=1
  xdebug.profiler_enable=0
  xdebug.remote_handler=dbgp
  xdebug.remote_mode=req
 
  xdebug.remote_port=9000
  xdebug.remote_host=dockerhost
  xdebug.idekey=PHPSTORM

参考)
http://laradock.io/#edit-xdebug-ini-files

imageの作り直し

docker imageを作り直します。

docker-compose up --build -d php-fpm
477-php-docker-xdebug_1.png

docker-compose.ymldepends_on にて、workspace が指定されているため、workspace も作り直されました。

477-php-docker-xdebug_2.png

nginxとmysqlも立ちあげときます。

477-php-docker-xdebug_3.png

PhpStormの設定調整

ここでは、以下のように設定しておきます。

477-php-docker-xdebug_4.png 477-php-docker-xdebug_5.png

デバッグ接続をリッスン状態にします。
(start Listening for PHP Debug Connections)

477-php-docker-xdebug_6.png

以下コマンドで、9000ポート でリッスン状態となっていることが確認できます。

477-php-docker-xdebug_7.png

これで、以下のようにリモートデバッグを行えるようにしたつもりです。

1. コンテナにリクエストが到達すると、

2. コンテナ上のXdebugが、ホストマシン(今回は192.168.11.10)の
   9000ポートに対してDBGPの接続通信を行う。

3. DBGPの接続が確立してデバッグが行える。

しかし、PhpStorm上でデバッグが開始されませんでした。原因を調べてみます。

XDebugのlogを確認

xdebug_log を出力するようにして、不具合の原因を確認します。

イメージを作り直すのが手間だったので、直接コンテナを修正します。

docker-compose exec php-fpm bash

コンテナ内に vim がインストールされてなかったのでインストールします。

apt-get update
apt-get install vim

xdebug.ini を編集します。

vi /usr/local/etc/php/conf.d/xdebug.ini

XDebugのログが /tmp/xdebug_log に出力されるように、下記内容を追記します。

xdebug.remote_log="/tmp/xdebug_log"

設定反映させるため、コンテナの停止・稼働を行います。

docker container stop laradock_php-fpm_1
docker container start laradock_php-fpm_1
477-php-docker-xdebug_9.png

コンテナにHTTPリクエスト実施後、ログを確認してみます。
下記コマンドで確認できます。

docker-compose exec php-fpm cat /tmp/xdebug_log
477-php-docker-xdebug_10.png

原因は「remote_connect_back」

ログをみてみたところ、192.168.11.10:9000 に接続するよう設定したつもりが、172.21.0.1:9000 に接続しています。

Nginx側で、dockerのGatewayからリクエストが来ているように見えているようです。

Gatewayは、下記のように確認できます。

477-php-docker-xdebug_11.png

この場合、下記設定を修正する必要があります。

xdebug.remote_connect_back=1

xdebug.remote_connect_back を有効にすると、$_SERVER['REMOTE_ADDR'] に対してDBGP接続通信を行うように試みるようです。

今回のケースでは、xdebug.remote_host で指定したIPに接続してもらいたいので、xdebug.remote_connect_back を無効にします。

XDebugの設定調整(再修正)

  • laradock/workspace/xdebug.ini
  • laradock/php-fpm/xdebug.ini

を以下のようにします。

xdebug.remote_autostart=1
xdebug.remote_enable=1
xdebug.remote_connect_back=0
xdebug.cli_color=1
xdebug.profiler_enable=0
xdebug.remote_handler=dbgp
xdebug.remote_mode=req
 
xdebug.remote_port=9000
xdebug.remote_host=dockerhost
xdebug.idekey=PHPSTORM

修正後、イメージを作り直して動作確認したところ、無事リモートデバッグができるようになりました。

477-php-docker-xdebug_12.png

参考

わくわくBank.
フリーランスのエンジニアとして活動してます。ここでは、ソフトウェア開発で必要とされる技術、用語、概念を整理しています。