Help us understand the problem. What is going on with this article?

Dockerで古いPHP(5.x)のXdebugを組み込んだデバッグ環境を構築する

More than 1 year has passed since last update.

はじめに

新しい技術が好きな技術者といえども、古いシステムの改修や保守のために既にサポートが切れてしまっているようなバージョンのソフトウェアを触ることになる、という経験は誰しも訪れる。

そんなとき、古い開発環境をわざわざインストールしたくない。

ならば仮想化技術の出番でしょう。

追記 1

mac OSでうまく動かなかったので対処しました。
mac OSの場合は最終的にlocalhostにDockerコンテナ内のportがマッピングされるので、http://localhost/でアクセスできるようになります。
詳しくはDocker公式 Networking features in Docker for Mac の項を参照

作成したコードはこちらのgithubリポジトリにあります。

追記 2

mac OSではXdebugでのブレークポイントが確認できていません。
こちらのGistを元に、コンテナ内からhostのmac OSに接続できるように設定してあげれば良いはずなのですが・・・

やること

  • Dockerを使って、ローカル環境を汚さずにPHP5.3を実行できるhttpdサーバーを立てる開発環境を構築する
  • VSCodeからPHPにデバッグをかけ、ブレークポイントを張る

最終形のファイル構成

このような形で進めていきます。

publicの中には、webコンテンツが、logsの中にはapacheのログファイルが入ります。

.
├── docker-compose.yml
├── Dockerfile
├── logs
│   ├── access_log
│   ├── error_log
│   └── .gitkeep
├── public
│   ├── index.php
│   └── phpinfo.php
├── README.md
└── .vscode
    └── launch.json

Dockerのバージョン確認

Dockerのバージョンを念の為に確認します。

$ docker -v
Docker version 17.09.0-ce, build afdb6d4

$ docker-compose -v
docker-compose version 1.15.0, build e12f3b9

Dockerを使って、ローカル環境を汚さずにPHP5.3を実行できるhttpdサーバーを立てる開発環境を構築する

ここはもう、えいやと、Dockerfileとdocker-compose.ymlを作成します。

こちらのDockerfileを大いに参考にしました。

Dockerfile
FROM centos:6.6

# set repository
RUN rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm

# install httpd
RUN yum -y install httpd vim-enhanced bash-completion unzip

# install php
RUN rpm --rebuilddb; yum install -y php php-mysql php-devel php-gd php-pecl-memcache php-pspell php-snmp php-xmlrpc php-xml

# Install xdebug for php debugging
RUN yum install -y php-pecl-xdebug
RUN echo "xdebug.default_enable = 1" > /etc/php.d/xdebug_settings.ini \
    && echo "xdebug.remote_enable=on" >> /etc/php.d/xdebug_settings.ini \
    && echo "xdebug.remote_autostart=on" >> /etc/php.d/xdebug_settings.ini \
    && echo "xdebug.remote_connect_back = on" >> /etc/php.d/xdebug_settings.ini \
    && echo "xdebug.remote_port = 9000" >> /etc/php.d/xdebug_settings.ini

EXPOSE 80

# Start web server
CMD ["httpd", "-D", "FOREGROUND"]
docker-compose.yml
php-debug:
  build: .
  environment:
    # replace with your local IP
    XDEBUG_CONFIG: remote_host={{192.168.179.3}} 
  volumes:
    # ローカルのWebコンテンツをマウント
    - ./public:/var/www/html
    # Apacheのlogファイルをローカルに書き出してもらうために、logsをマウント
    - ./logs:/var/log/httpd

docker-compose.ymlファイルを作成するのは、2つ理由があります。
- MySQLなどのDBコンテナを簡単に連携させるため(この記事内でDB接続はしません)
- この開発環境を利用する開発者各自のローカル環境に依存する設定をコンテナ定義の外側に出すため

Dockerのビルドの前に、開発端末のlocal IPを調べて、docker-compose.ymlを書き換える必要があります。

ip a // linux, macOS
ipconfig // windows

次のコマンドを実行して、Dockerのビルドと実行をします。
最初はイメージやライブラリのダウンロードとインストールがあるので、それなりに時間がかかります。

docker-compose build
docker-compose up

ここまで実行すると、次のようなメッセージがコンソールに表示され、httpdサービスがコンテナ内で動作している状態になります。

Recreating phpdebug_php-debug_1 ... 
Recreating phpdebug_php-debug_1 ... done
Attaching to phpdebug_php-debug_1
php-debug_1  | httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.3 for ServerNam

表示されているIPアドレスをブラウザに打ち込んでみましょう。

Apache 2 Test Page
powered by CentOS

と表示されていれば成功です。

あとは、コンテナ内の/var/www/htmlにマウントしているディレクトリの中にphpinfo.phpを作成して、ちゃんとマウントされているかも確認しておきましょう。

phpinfo.php
<?
    phpinfo();
?>

ブラウザに 172.17.0.3/phpinfo.php と入力してphpinfo()の内容が見れるか確認しましょう。

VisualStudioCodeからPHPにデバッグをかけ、ブレークポイントを張る

Xdebugの機能でPHPのデバッグを行うのは、VisualStudioCode限定ではないのですが、有料のPhpStormを除けば、一番手軽だと思うので、VisualStudioCodeでデバッグをしてみます。

手順はとても簡単です。

  • VisualStudioCodeにphp-debugの拡張をインストール
  • デバッグでXdebug向け構成を作成
  • デバッガ起動
  • 動作を確認したいphpコードにブレークポイントを張る
  • phpファイルにブラウザからアクセス

VisualStudioCodeにphp-debugの拡張をインストール

拡張の検索で、 php-debug と入力してさくっとインストールしてください。

ブレークポイントを張るという目的ならば必要ありませんが、がっつり開発したいなら、好みで、php-intellisenseを入れましょう。
機能を最大限使うためには、ローカル環境にphp 7コマンドをインストールしてあげる必要があります。

デバッグでXdebug向け構成を作成

デバッグ構成の追加でlaunch.jsonファイルを生成して、内容は以下のようにします。

.vscode/launch.json
{
  "version": "0.2.0",
  "configurations": [

    {
      "name": "Listen for XDebug",
      "type": "php",
      "request": "launch",
      "port": 9000,
      "pathMappings": {
        "/var/www/html": "${workspaceRoot}/public"
      }
    }
  ]
}

デフォルト生成状態では追加されない項目が以下の2つですが、ブレークポイントを張るためには重要なので、設定を追加してください。
localSourceRootは、ローカル環境に置いてある、デバッグ対象のWebコンテンツルートを指定します。この記事の例では、同じプロジェクトディレクトリにあるので、${workspaceRoot}を使っていますが、そうでない場合は、絶対パスでgitリポジトリを指定するなどしましょう。
serverSourceRootはコンテナ内のWebコンテンツルートを指定します。

デバッガ起動

VisualStudioCodeのデバッグ構成からListen for XDebugを選択して、デバッグ開始します。

動作を確認したいphpコードにブレークポイントを張る

試しにということで、次のようなファイルを作成してみます。

index.php
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <div style="background-color:lightgray;">
    <?php
    $a = "world";
    echo "hello " . $a . " <br/>";
    echo "from xdebug!";
?>
    </div>

</body>
</html>

phpコード内の任意の行にブレークポイントを張りました。
Screenshot from 2017-10-06 01-28-30.png

phpファイルにブラウザからアクセス

ブレークポイントを張った状態でブラウザから対象のphpファイルにアクセスすると、ブラウザが応答待ちになり、VisualStudioCode側はブレークポイントで待機状態となります。

ちゃんと、変数の内容も表示されていますね。
Screenshot from 2017-10-06 01-33-56.png

補足

xdebugの設定で、remoteポートを9000を設定したのに、DockerfileでEXPOSEしなかったことに疑問を持った方がいるかもしれません。
これは、VisualStudioCodeが9000でListenして、そこにコンテナ内のxdebugがアクセスするという仕組みになっているため、コンテナ内→外の通信なのでポート開放する必要がないというわけです。

よーくVisualStudioCodeのデバッグ設定を見てみると、「Listen for XDebug」 となっていて、9000番ポートの通信を待っているのはVisualStudioCodeの方ということになります。
このあたりは、Debugger for Chromeと通信方向が逆なので勘違いしやすいかもしれません。
(Chromeデバッグモードは、9222ポートで通信を待っているので、エディタ側が接続しに行く)

yoskeoka
Gopherです。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした