从 Docker 容器内部使用 XDebug 进行远程调试不起作用

Posted

技术标签:

【中文标题】从 Docker 容器内部使用 XDebug 进行远程调试不起作用【英文标题】:Remote Debugging with XDebug from inside a Docker Container does not work 【发布时间】:2015-08-16 04:05:08 【问题描述】:

我正在尝试设置一个停靠的 AMP 环境,但无法让远程调试器正常工作。我的设置如下:

我有一个运行 mysql 的数据库容器,它的工作就像一个魅力。我使用以下 Dockerfile 构建了一个 Docker 映像“phpmysqli”

FROM php:apache

RUN docker-php-ext-install mysqli mbstring

# zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20131226/xdebug.so
RUN pecl install xdebug
RUN echo 'zend_extension = /usr/local/lib/php/extensions/no-debug-non-zts-20131226/xdebug.so' >> /usr/local/etc/php/php.ini
RUN touch /usr/local/etc/php/conf.d/xdebug.ini; \
    echo xdebug.remote_enable=1 >> /usr/local/etc/php/conf.d/xdebug.ini; \
    echo xdebug.remote_autostart=0 >> /usr/local/etc/php/conf.d/xdebug.ini; \
    echo xdebug.remote_connect_back=1 >> /usr/local/etc/php/conf.d/xdebug.ini; \
    echo xdebug.remote_port=9000 >> /usr/local/etc/php/conf.d/xdebug.ini; \
    echo xdebug.remote_log=/tmp/php5-xdebug.log >> /usr/local/etc/php/conf.d/xdebug.ini;

RUN echo 'date.timezone = Europe/Berlin' > /usr/local/etc/php/conf.d/date.ini

我打电话

docker run --rm -ti  --name web -p 127.0.0.1:8080:80 -v /path/to/projects:/var/www/html --link db:db  phpmysqli

在这个 phpinfo 之后分别 php -i 显示 xdebug 2.3.2 已经启动并运行。

接下来,我在 IntelliJ IDEA 中设置了一个名为“Docker”的服务器,主机 127.0.0.1、端口 8080 和调试器 Xdebug。我设置了类似于 docker run 语句中的卷映射的路径映射。

PHP->调试设置中,我检查了我使用端口9000 进行传入连接,我将接受外部连接并且我不会忽略来自未注册服务器的连接。

在此之后,我还创建了一个名为 Docker 的新 PHP 远程调试配置。服务器是 Docker,会话 id 是XDEBUG_IDEA

我可以调用容器上的 PHP 文件,我可以通过链接连接到数据库...但是由于某种原因,当我尝试启动调试会话时没有任何反应。我尝试使用 cookie(是的,我在 xdebug 助手中将 XDEBUG_IDEA 设置为会话 ID)。我尝试将XDEBUG_SESSION_START=XDEBUG_IDEA 发送为GET...

各位聪明人能告诉我我错过了什么吗?

【问题讨论】:

不知道出了什么问题,但您应该使用docker exec -it web_id bash 在您的容器中连接并在其中进行调试,就像在任何有此类问题的 Linux 服务器上一样 您在 Windows 上吗?如果是,您在 Docker 主机上使用什么? (流浪汉,其他?) 我正在运行 Ubuntu 15.04 尝试一种解决方法:使用docker run --net=host 启动您的容器(并删除-p 127.0.0.1:8080:80)。这将使您的容器和 Docker 主机共享相同的网络接口。因此,从容器的角度来看,localhost 将是 Docker 主机。 xdebug 在弄清楚如何连接到调试器时可能会更轻松 这与--link不兼容 【参考方案1】:

您可以尝试使用此配置。 php-apache build 提供了两种方法来编译和启用模块 php。 最好使用docker-php-ext-enable xdebug 来设置正确的文件配置。

FROM php:5.4-apache

# Enable and configure xdebug
RUN pecl install xdebug
RUN docker-php-ext-enable xdebug
RUN sed -i '1 a xdebug.remote_autostart=true' /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN sed -i '1 a xdebug.remote_mode=req' /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN sed -i '1 a xdebug.remote_handler=dbgp' /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN sed -i '1 a xdebug.remote_connect_back=1 ' /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN sed -i '1 a xdebug.remote_port=9000' /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN sed -i '1 a xdebug.remote_host=127.0.0.1' /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN sed -i '1 a xdebug.remote_enable=1' /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini

【讨论】:

我试过“pecl install xdebug”,它返回一个错误:pecl/xdebug 需要 PHP(版本 >= 5.5.0),安装的版本是 5.4.45 没有找到有效的包安装失败 我有同样的错误。我将“FROM php:5.4-apache”更改为“FROM php:7.0-apache”,它解决了我的问题 :) 请阅读有关xdebug.remote_connect_back 的文档,它告诉您:如果启用,xdebug.remote_host 设置将被忽略,Xdebug 将尝试连接到发出 HTTP 请求的客户端。它检查 $_SERVER['HTTP_X_FORWARDED_FOR'] 和 $_SERVER['REMOTE_ADDR'] 变量以找出要使用的 IP 地址。显然,启用它后,remote_host ip 设置将被忽略。【参考方案2】:

对于我在使用 sublime 的 PHP、nginx Docker 环境中,我让它可以使用以下设置:

xdebug.remote_enable = 1
xdebug.remote_mode = req
xdebug.remote_port = 9001
xdebug.remote_connect_back=0
xdebug.remote_host=host.docker.internal

我花了很长时间才弄清楚的一个是将 remote_host 设置为 host.docker.internal。

【讨论】:

host.docker.internal 仅适用于 Docker for Windows 或 Docker for Mac,不适用于在 linux 环境中运行的 Docker。 ***.com/questions/48546124/… @bender 现在已经不是这样了:github.com/moby/moby/pull/40007#issuecomment-578729356 如果您尝试在 WSL2 下配置 xdebug,请注意 host.docker.internal 不指向子系统,需要解决方法:***.com/questions/62104199/…【参考方案3】:

关闭:xdebug.remote_connect_back=0 添加:xdebug.remote_host=192.168.0.102[your docker host/machine IP]

【讨论】:

【参考方案4】:

如果您不想更改容器中的 xdebug 配置并希望使用 xdebug.remote_connect_back=1 使其工作,您可以将 HTTP-Header X-Forwarded-For 设置为 host.docker.internal 的 IP,从而定义 PHP $_SERVER['HTTP_X_FORWARDED_FOR'] xdebug 更喜欢并将其用作客户端 IP 而不是 $_SERVER['REMOTE_ADDR']

【讨论】:

【参考方案5】:

在 Docker 20.10+ 中,Xdebug 使用这种违反直觉的配置同时适用于 Ubuntu 和 MacOS 用户:

xdebug.client_host=host.docker.internal
xdebug.discover_client_host=true

使用 PhpStorm 测试。用于构建具有网络功能和 Xdebug 功能的基于 PHP7+ debian 的容器,无论您运行什么操作系统(可能是 Windows,但尚未尝试)。

【讨论】:

以上是关于从 Docker 容器内部使用 XDebug 进行远程调试不起作用的主要内容,如果未能解决你的问题,请参考以下文章

phpStorm中使用xdebug工具调试docker容器中的程序

工具系列 | PHPSTROM 连接Docker容器 && 配置XDEBUG调试

在 Docker for Mac 上使用 SSH 隧道进行 Xdebug

Visual Studio Code IDE + Docker实现PHP Xdebug调试

在Docker中安装xdebug

无法从我的 Docker 容器内部连接到主机的 localhost