IDE 使用 Docker、nginx、PHP7-FPM 和 Xdebug 进行调试

IDE debugging with Docker, nginx, PHP7-FPM and Xdebug

我目前正在使用 docker-compose 在 macOS 上准备一个开发堆栈,以便能够在 [= 上使用 Xdebug(端口:9009) 108=]-FPM(端口:9000)和nginx(端口:80)server.

显然配置没问题,但我无法通过IDE进行调试。

这是我的设置:

我的 .env 文件:

APP_NAME=testeXdebug
HOST_SERVER_NAME=myapp
HOST_IP=docker.for.mac.localhost
# Use docker.for.mac.localhost - for OS X
# Use docker.for.win.localhost - for Windows

Dockerfile PHP7-FPM + Xdebug:

FROM php:7.2-fpm

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

docker-compose.yml 文件:

version: '3.5'

services:
  web:
    image: nginx:1.15.2
    ports:
      - '80:80'
    volumes:
      - '.:/usr/share/nginx/html'
      - './config/default.conf:/etc/nginx/conf.d/default.conf'
      - '/tmp/${APP_NAME}/web:/var/log/nginx'
    env_file:
      - '.env'
    depends_on:
      - 'php-fpm'
    links:
      - 'php-fpm'

  php-fpm:
    build: './docker'
    ports:
      - '9000:9000'
      - '9009:9009'
    expose:
      - 9000
      - 9009
    volumes:
      - '.:/usr/share/nginx/html'
      - './config/php-dev.ini:/usr/local/etc/php/conf.d/php-dev.ini'
      - '/tmp/${APP_NAME}/php-fpm:/var/log/xdebug'
    environment:
      XDEBUG_CONFIG: "remote_host=${HOST_IP}"
      PHP_IDE_CONFIG: "serverName=${HOST_SERVER_NAME}"
    env_file:
      - '.env'

php-dev.ini 文件:

; Xdebug
xdebug.default_enable = 1
xdebug.remote_enable = 1
xdebug.remote_autostart = 1
xdebug.remote_connect_back = 1
xdebug.remote_port = 9009
xdebug.profiler_enable = 0
xdebug.idekey = PHPSTORM
xdebug.remote_handler = dbgp
xdebug.remote_mode = req
xdebug.remote_log = /var/log/xdebug/xdebug.log

nginx default.conf 文件:

server {
    listen          80;
    server_name     myapp;
    root            /usr/share/nginx/html;
    index           index.php index.html index.htm;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass    php-fpm:9000;
        fastcgi_index   index.php;
        fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include         fastcgi_params;
    }

    location ~ /\.ht {
        deny  all;
    }
}

然后当通过具有Xdebug helper扩展名的浏览器访问服务器时:

我得到这个调试日志 (xdebug):

Log opened at 2018-08-11 19:22:53
I: Checking remote connect back address.
I: Checking header 'HTTP_X_FORWARDED_FOR'.
I: Checking header 'REMOTE_ADDR'.
I: Remote address found, connecting to 192.168.128.1:9009.
I: Connected to client. :-)
-> <init xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" fileuri="file:///usr/share/nginx/html/index.php" language="PHP" xdebug:language_version="7.2.8" protocol_version="1.0" appid="9" idekey="PHPSTORM"><engine version="2.6.1"><![CDATA[Xdebug]]></engine><author><![CDATA[Derick Rethans]]></author><url><![CDATA[http://xdebug.org]]></url><copyright><![CDATA[Copyright (c) 2002-2018 by Derick Rethans]]></copyright></init>

-> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" status="stopping" reason="ok"></response>

Log closed at 2018-08-11 19:22:53

nginx访问日志:

192.168.128.1 - - [11/Aug/2018:18:57:25 +0000] "GET /favicon.ico HTTP/1.1" 200 94197 "http://docker.for.mac.localhost/index.php?XDEBUG_SESSION_START=PHPSTORM" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36" "-"
192.168.128.1 - - [11/Aug/2018:19:22:53 +0000] "GET /index.php?XDEBUG_SESSION_START=PHPSTORM HTTP/1.1" 200 94341 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36" "-"
192.168.128.1 - - [11/Aug/2018:19:22:53 +0000] "GET /favicon.ico HTTP/1.1" 200 94205 "http://docker.for.mac.localhost/index.php?XDEBUG_SESSION_START=PHPSTORM" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36" "-"
192.168.128.1 - - [11/Aug/2018:19:30:12 +0000] "GET /_intellij_phpdebug_validator.php HTTP/1.1" 200 516 "-" "Java/1.8.0_152-release" "-"

并使用调试扩展设置 VSCode:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Listen for XDebug",
            "type": "php",
            "request": "launch",
            "port": 9009,
            "pathMappings": {
                "/usr/share/nginx/html": "${workspaceRoot}"
            }
        }
    ]
}

添加一些断点:

PhpStorm 上:

PhpStorm CLI 解释器使用 docker-compose:

但是在 开始侦听 PHP 调试连接 我得到 Port 9009 is busy.

并且IDE从不启动调试工具... =(
我会错过什么?请帮助我!


经过一些评论:

docker-compose.yml

中删除 php-fpm 服务的 portsexpose 设置时
thiago@MA-TPR testeXdebug $ docker ps
CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS                NAMES
735fc48fad63        nginx:1.15.2          "nginx -g 'daemon of…"   4 minutes ago       Up 4 minutes        0.0.0.0:80->80/tcp   testexdebug_web_1
b9b16af98fb5        testexdebug_php-fpm   "docker-php-entrypoi…"   4 minutes ago       Up 4 minutes        9000/tcp             testexdebug_php-fpm_1
thiago@MA-TPR testeXdebug $ 

并从 xdebug 获取此日志:

Log opened at 2018-08-12 00:56:39
I: Checking remote connect back address.
I: Checking header 'HTTP_X_FORWARDED_FOR'.
I: Checking header 'REMOTE_ADDR'.
I: Remote address found, connecting to 192.168.160.1:9009.
W: Creating socket for '192.168.160.1:9009', poll success, but error: Operation now in progress (29).
E: Could not connect to client. :-(
Log closed at 2018-08-12 00:56:39

正在从 PHP 容器执行 nc

root@b9b16af98fb5:/var/www/html# nc -zv docker.for.mac.localhost 9009
Warning: inverse host lookup failed for 192.168.65.2: Unknown host
docker.for.mac.localhost [192.168.65.2] 9009 (?) open
root@b9b16af98fb5:/var/www/html# 

But at Start listening for PHP Debug connection I get Port 9009 is busy

不需要在您的 Docker 容器中公开 Xdebug 端口,根本不需要。

如果你公开它.. Docker 将是监听该端口并将任何连接转发到容器的那个。但是 IDE/VSCode/PhpStorm 必须在监听它...因为 它是连接到 IDE 的 Xdebug,而不是其他方式

先解决这个问题。

xdebug.remote_connect_back = 1

我建议关闭此功能并在 xdebug.remote_host (docker.for.mac.localhost) 中指定实际主机。

Xdebug 使用 remote_connect_back 选项检测到的 IP(取决于我猜测的设置,以及 Docker 的工作方式)很可能不是主机的 IP。但这正是您所需要的——那是您的 IDE (PhpStorm) / 编辑器 (VSCode) 运行并且 Xdebug 必须连接到的地方。

如果你在 "Docker for Mac",那么在你的 xdebug 配置文件中你也可以使用这个:

xdebug.remote_host = host.docker.internal

I WANT TO CONNECT FROM A CONTAINER TO A SERVICE ON THE HOST
The host has a changing IP address (or none if you have no network access). From 18.03 onwards our recommendation is to connect to the special DNS name host.docker.internal, which resolves to the internal IP address used by the host. This is for development purpose and will not work in a production environment outside of Docker for Mac.

网关也可以访问 gateway.docker.internal。