lycheejam's tech log

チラ裏のメモ帳 | プログラミングは苦手、インフラが得意なつもり。

VSCode + Docker + XdebugでPHPのデバッグ環境を構築

概要

前回、Docker(nginx + PHP-FPM)を使ってPHPの実行環境を構築しました。
基本構文を覚えたばかりなのでコード毎に動作を追いたいと思った次第です。

Docker(nginx + PHP-FPM + Xdebug)+ VisualStudio Codeでデバッグが行える環境を構築します。

前回作成したDocker(nginx + PHP-FPM)のPHP実行環境にXdebugを追加する形で構築します。

前回の環境構築記事は以下です。

kitigai.hatenablog.com

目次

参考サイト様

環境

$ docker -v
Docker version 18.09.2, build 6247962
$ docker-compose -v
docker-compose version 1.23.2, build 1110ad01

デバッグ環境の構築

DockerのnginxとPHP-FPMコンテナで構成されたPHP実行環境です。
前回は、PHP-FPMコンテナに公式イメージを使用していましたが
今回は同じイメージをベースにDockerfileを作成しXdebugをコンテナにインストールします。

そしてVisualStudio Code上でデバッグが実行できるようにします。

成果物

github.com

ディレクトリ構成

$ tree .
.
├── docker-compose.yml
├── docker-configs
│   ├── nginx
│   │   └── nginx.conf
│   └── php-fpm
│       ├── Dockerfile
│       └── xdebug.ini
└── src
    └── index.php

nginxのconfigファイル作成

nginxについては前回と変わりないので解説なしです。
confファイルのみ載せておきます。
下記の前回記事をご参照ください。

server {
  listen 80;
  server_name localhost;

  root  /var/phpapp;
  index index.php index.html;

  location / {
    try_files $uri $uri/ /index.php$is_args$args;
  }
  # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
  #
  location ~ \.php$ {
     fastcgi_pass   php:9000;
     fastcgi_index  index.php;
     fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
     include        fastcgi_params;
  }
}

Dockerfileの作成

PHP-FPMのDockerイメージをベースにXdebugをインストールします。
インストールコマンドについては公式ドキュメントに従います。
また、DockerHubのPHPイメージのページにも記載がありました。

下記のパスでPHP-FPM用のDockerfileを作成します。

  • docker-configs/php-fpm/Dockerfile
FROM php:7-fpm

RUN pecl install xdebug && \
    docker-php-ext-enable xdebug

コンテナ作成時にpeclコマンドでXdebugをインストールします。
そして、docker-php-ext-enableコマンドで拡張機能を有効化します。

peclって?

peclと言うコマンドを初めて見たので「んんん???」となりましたが下記の記事がわかりやすく参考になりました。

dockerコンテナでしか見てないんですがCentOSだとデフォルトでインストールされてるっぽいんですかね?

$ docker run -it centos bash
[root@5245070f6cfc /]# cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)
[root@5245070f6cfc /]# yum provides pecl
//省略
1:php-pear-1.9.4-21.el7.noarch : PHP Extension and Application Repository framework
Repo        : base
Matched from:
Filename    : /usr/bin/pecl

docker-compose.ymlの作成

前回記事同様にdocker-compose.ymlを作成します。

  • docker-compose.yml
version: "3.7"
services:

  web:
    image: nginx:latest
    ports:
      - "8080:80"
    volumes:
      - ./docker-configs/nginx/nginx.conf:/etc/nginx/conf.d/default.conf
  php:
    build: './docker-configs/php-fpm'
    volumes:
      - ./src/:/var/phpapp/
      - ./docker-configs/php-fpm/xdebug.ini:/usr/local/etc/php/conf.d/xdebug.ini

前回からの変更点はphpセクションをimageからbuildに変更し、先程作成したDockerfileを使用してコンテナが作成されるように変更しました。

また、この後で作成しますがxdebug.iniXdebugの設定ファイル)をマウントしています。

xdebug.iniの作成

Xdebug用の設定ファイルを作成します。
公式ドキュメントの下記を参考に設定します。
また、日本語での解説記事とStackOverflowが参考になりました。

下記のパスでxdebug.iniを作成します。

  • docker-configs/php-fpm/xdebug.ini
[xdebug]
; リモートデバッグ有効化
xdebug.remote_enable = On
; ホスト指定(host.docker.internalはMac以外じゃ使えない)
xdebug.remote_host = host.docker.internal
; ホスト側のポート指定
xdebug.remote_port = 9000
; リモートデバッグの自動開始
xdebug.remote_autostart = On

host.docker.internalって

Dockerコンテナからホストに接続する際に使える便利なやつ。 ただドキュメントにはDocker Desktop for Mac以外じゃ使えないよって記載があるのでWindowsの場合はがんばってください。

VisualStudio Code側の設定

次はVS Code側で操作します。

VS CodeXdebug拡張をインストール

拡張機能から「xdebug」をインストールします。

f:id:HM_Atlas:20190504163517p:plain

デバッグ構成の追加

メニューからデバッグ構成の追加...を押下すると下記画像の様に選択肢が出るのでPHPを選択します。
すると.vscode配下にlaunch.jsonが作成されるのでそれを編集します。

構成追加 環境選択 できた
f:id:HM_Atlas:20190504163546p:plain f:id:HM_Atlas:20190504163603p:plain f:id:HM_Atlas:20190504163618p:plain

launch.jsonの設定内容については下記の公式ドキュメントを参考に設定します。

抜粋します。
編集箇所にコメントをつけてます。

  • .vscode/launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Listen for XDebug",
      "type": "php",
      "request": "launch",
      "port": 9000,
      //下記を追加
      "pathMappings": {
          "/var/phpapp": "${workspaceRoot}/src"
      }
    },
    //省略
  ]
}

pathMappingsPHPファイルのディレクトリ(コンテナ側のパスとホスト側のパス)を指定します。
${workspaceRoot}はプロジェクトのルートディレクトリになります。
stopOnEntrytrueにするとデバッグ開始時に自動的にコード先頭で止まってくれます。

デバッグの実行

Docker Composeでコンテナを起動します。

$ docker-compose up

VSCodeからデバッグを開始してブレークポイントを設定します。

f:id:HM_Atlas:20190504163702p:plain

そして、ブラウザからhttp://localhost:8080へアクセスするとブレークポイントで停止することが確認できます。

トラブルシュート:Cannot load Xdebug - it was already loadedが発生する。

docker-compose upでコンテナを起動するとコンテナ自体は上がってるっぽいですがエラーが発生していてデバッグができませんでした。
デバッグを開始してもうんともすんとも言わない状況。

原因はxdebug.inizend_extensionを指定していたことが原因でした。

[xdebug]
; 下記を指定しているとエラーが発生した。
zend_extension="/usr/local/lib/php/extensions/no-debug-non-zts-20180731/xdebug.so"
xdebug.remote_enable = On
xdebug.remote_host = host.docker.internal
xdebug.remote_port = 9000
xdebug.remote_autostart = On

このzend_extensionxdebug.iniへ追加したのはコンテナ初回起動時のログに下記を追加してねと出力されていたので追加した次第なんですが...

zend_extension="/usr/local/lib/php/extensions/no-debug-non-zts-20180731/xdebug.so"

下記の類似のStackOverflowを参考にとりあえずパスの指定をコメントアウトしたら動きました。

雑感

ホントはPHPCRUDやってみよーと初めたんですが「え、PHPデバッグechovar_dumpのみ???」となってしまったので環境作ってみました。
PHPはわかんないことだらけで時間がかかりますね...