从 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