こんにちは!日々のLaravel開発、お疲れ様です。
機能の実装に行き詰まったとき、あなたはどうやってバグの原因を探っていますか?
「あちこちに `dd()` や `Log::info()` を仕込んで、ブラウザをリロードして確認する……」
もし、そんな泥臭いデバッグをまだ続けているなら、今日でそのスタイルとはお別れしましょう。
今回紹介する Xdebug をマスターすれば、あなたのIDE(PhpStormやVS Codeなど)からコンテナの中を完全に覗き見できるようになります。変数の値はリアルタイムで変化し、怪しい処理の数ステップ前でコードを一時停止(ブレークポイント)させ、意図した通りのデータが入っているかを一目で確認できるようになります。
これを導入するだけで、毎日のコーディングとエラー調査のストレスは劇的に軽減されますよ。さあ、Docker環境でのLaravel開発を最高にスマートにする冒険に出かけましょう!
—
1. なぜDocker×Xdebugの連携はハマりやすいのか?(本質の理解)
まず最初に、なぜDocker環境でのXdebug設定が「初心者泣かせ」と言われるのか、その理由をアーキテクトの視点からスッキリ整理しておきましょう。
通常のローカル環境であれば、Xdebugは「同じマシン内」で動いているため、IDEとの通信は比較的簡単です。しかし、Dockerを使うと状況が変わります。
PHPは「Dockerという頑丈なカプセル(コンテナ)の中」で動いており、あなたのIDEは「ホストマシン(あなたの手元のPC)」で動いています。
つまり、
1. コンテナ内でエラーやブレークポイントにヒットしたPHPが、
2. 「おい、俺を止めたぞ!誰かデバッグ情報をくれ!」と外部へ助けを求めようとするものの、
3. カプセルの中からは外の世界(ホストマシン)がどこにあるか見えないため、通信が迷子になってしまう――これがハマる最大の原因です。
この「見えない壁」を突破するための魔法の呪文が、これから設定する `host.docker.internal` や適切なリモートデバッグポートの指定なのです。
—
2. Docker環境におけるXdebugの全体像
私たちが目指すゴールは、以下の通信経路を確立することです。
[ ホストマシン (あなたのPC) ]
- IDE (PhpStorm / VS Code) <--- 9003番ポートで待ち構えている(リスナー起動中)
▲
│ (TCP通信 / デバッグデータ)
▼
[ Docker コンテナ (PHP-FPM / Laravel) ]
- Xdebug —> host.docker.internal:9003 向けて発信
この構造さえ頭に入っていれば、設定ファイルで何を記述しているのかが手に取るようにわかるようになります。
—
3. 実践!Laravel + Dockerでの設定テンプレート
それでは、実際のプロジェクトに組み込む具体的な設定ファイルを見ていきましょう。今回は多くの現場で採用されている `Dockerfile` (またはビルド引数), `docker-compose.yml`, そして `php.ini` の構成をベースに解説します。
① Dockerfile への Xdebug インストールと組み込み
まずは、PHPコンテナ内にXdebug拡張モジュールをインストールします。ここではPECLを使用して安全かつ確実に導入します。
既存のPHPイメージ(例: PHP 8.2 FPM)をベースにする
FROM php:8.2-fpm
1. 必要なシステム依存パッケージのインストール
RUN apt-get update && apt-get install -y \
git \
unzip \
libzip-dev \
libpng-dev \
&& docker-php-ext-install zip pdo_mysql gd
2. Xdebugのインストールと有効化
PECL経由で安定版のxdebugをビルドし、PHPの拡張モジュールとして登録します
RUN pecl install xdebug-3.2.1 \
&& docker-php-ext-enable xdebug
Composerのインストール(Laravel開発の必須要件)
COPY –from=composer:latest /usr/bin/composer /usr/bin/composer
WORKDIR /var/www/html
② php.ini (または設定ファイル) でのXdebug詳細設定
次に、Xdebugの挙動を制御するパラメータを設定します。コンテナ内の `/usr/local/etc/php/conf.d/xdebug.ini` などとしてマウント、または配置するのが一般的です。
[xdebug]
; デバッグモードを有効化(ステップデバッグ、プロファイルなどを一括制御)
xdebug.mode = debug
; スクリプト開始時に自動でデバッグ接続を開始させない(ブレークポイントにヒットした時だけ発動)
xdebug.start_with_request = yes
; Xdebugが通信を試みるホスト側のIP/ホスト名
; Docker公式が提供する、ホストマシンを指す名前解決用エイリアスを指定します
xdebug.client_host = host.docker.internal
; IDE側でリスニングするポート(Xdebug v3のデフォルトは9003)
xdebug.client_port = 9003
; ログ出力設定(接続トラブル時にどこで躓いているか一発でわかるため、必ず有効に推奨)
xdebug.log = /var/log/xdebug.log
xdebug.log_level = 7
> 先輩からのアドバイス:
> `xdebug.client_host = host.docker.internal` は、Docker Desktop(Mac / Windows)であればそのまま動作します。もし Linux 環境で Docker をお使いの場合は、ホスト側のブリッジネットワークのIP(通常 `172.17.0.1` など)を直接指定するか、docker-compose側で `extra_hosts` を定義する必要があります。
③ docker-compose.yml の設定
Dockerコンテナ側からホストマシンを正しく認識させるために、`docker-compose.yml` にも一手間加えます。
version: ‘3.8’
services:
app:
build:
context: .
dockerfile: Dockerfile
image: laravel-xdebug-app
container_name: laravel_app_container
restart: delegated
working_dir: /var/www/html
volumes:
- .:/var/www/html
environment:
- PHP_IDE_CONFIG=serverName=laravel-docker
# ★超重要:Linux環境や一部のDocker構成において、host.docker.internalを名前解決できるようにする設定
extra_hosts:
- “host.docker.internal:host-gateway”
networks:
- laravel-net
networks:
laravel-net:
driver: bridge
`extra_hosts: – “host.docker.internal:host-gateway”` を記述しておくことで、OSを問わずコンテナからホストマシンへ確実にパケットを届けられるようになります。
—
4. IDE(PhpStorm / VS Code)側の受け入れ準備
コンテナ側の準備ができたら、次はあなたの手元にあるIDEに「通信を受け取る準備」をさせます。
PhpStorm の場合
1. 右上の電話マークのアイコン(Start Listening for PHP Debug Connections)をクリックして、緑色(リスニング中)にします。
2. `Preferences` (設定) > `PHP` > `Servers` を開き、新規サーバーを追加します。
- Name: `laravel-docker` (docker-composeの `PHP_IDE_CONFIG` と一致させる)
- Host: `localhost` (または開発時のドメイン)
- Port: `80` (またはWebコンテナの公開ポート)
- Use path mappings: 有効にし、プロジェクトのルートディレクトリと、コンテナ内のパス (`/var/www/html`) をマッピングします。
Visual Studio Code の場合
1. 拡張機能から 「PHP Debug」 (Felix Becker氏のもの) をインストールします。
2. `.vscode/launch.json` に以下の設定を追加します。
{
“version”: “0.2.0”,
“configurations”: [
{
“name”: “Listen for Xdebug”,
“type”: “php”,
“request”: “launch”,
“port”: 9003,
“pathMappings”: {
“/var/www/html”: “${workspaceFolder}”
}
}
]
}
3. デバッグタブを開き、「Listen for Xdebug」を選択して実行(F5キーなど)します。
—
5. 動作確認:HelloWorldをデバッグしてみよう!
すべてのピースが揃いました。本当に正しく連携できるか、Laravelのコントローラーを使ってテストしてみましょう。
1. ブレークポイントを設置する
例えば `app/Http/Controllers/Controller.php` や、新しく作ったテスト用コントローラーのメソッド内(`return` の行など)の行番号の左側をクリックし、赤いポッチ(ブレークポイント)を置きます。
2. IDEのリスニングが有効であることを確認する
(PhpStormなら電話アイコンが緑、VS Codeならデバッグセッションが待機中であること)
3. ブラウザまたはAPIクライアント(Postmanやcurl)からアクセスする
該当のルート(例: `http://localhost/` など)にアクセスします。
奇跡の瞬間
ブラウザの読み込みが「ピクッ」と止まったまま、先ほど仕掛けた赤いポッチの行で処理がフリーズします。そしてあなたのIDEの画面にフォーカスが移り、「今、メモリ上にどんな変数やリクエストパラメータが存在しているか」の一覧が美しく表示されるはずです!
もしここで止まらなければ、先ほど設定したコンテナ内の `/var/log/xdebug.log` を覗いてみてください。「どこに接続しようとして失敗したか」のログが鮮明に残っているため、迷うことなく原因を特定できます。
—
まとめ
お疲れ様でした!これで、あなたもDocker環境におけるXdebugマスターの仲間入りです。
- Dockerのコンテナ内PHP と ホストのIDE は、`host.docker.internal` とポート `9003` で繋がっている。
- `extra_hosts` や `php.ini` の設定を正しく行えば、環境差異に怯える必要はない。
- `dd()` や `var_dump()` の海原に溺れる生活とは今日でサヨナラ。
この仕組みを一度手に入れてしまうと、もう元のデバッグ方法には戻れなくなります。ぜひあなたの開発環境にも導入して、快適で生産性の高いLaravelライフを満喫してくださいね!