使用Docker、nginx、PHP7-FPM和Xdebug进行IDE调试
我目前正在用docker compose在macOS上准备一个开发堆栈,以便能够在PHP7-FPM(端口:9000)和nginx(端口:80)服务器上使用Xdebug(端口:9009) 显然,配置还可以,但我无法通过IDE进行调试 以下是我的设置: 我的使用Docker、nginx、PHP7-FPM和Xdebug进行IDE调试,nginx,docker-compose,xdebug,php-7.2,fpm,Nginx,Docker Compose,Xdebug,Php 7.2,Fpm,我目前正在用docker compose在macOS上准备一个开发堆栈,以便能够在PHP7-FPM(端口:9000)和nginx(端口:80)服务器上使用Xdebug(端口:9009) 显然,配置还可以,但我无法通过IDE进行调试 以下是我的设置: 我的.env文件: APP_NAME=testeXdebug HOST_SERVER_NAME=myapp HOST_IP=docker.for.mac.localhost # Use docker.for.mac.localhost - for O
.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
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'
; 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
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;
}
}
Dockerfile
PHP7-FPM+Xdebug:
FROM php:7.2-fpm
RUN pecl install xdebug \
&& docker-php-ext-enable xdebug
docker compose.yml
文件:
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
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'
; 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
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;
}
}
php-dev.ini
文件:
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
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'
; 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
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;
}
}
nginxdefault.conf
文件:
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
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'
; 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
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):
并使用以下命令设置带有调试扩展名的VSCode:
{
"version": "0.2.0",
"configurations": [
{
"name": "Listen for XDebug",
"type": "php",
"request": "launch",
"port": 9009,
"pathMappings": {
"/usr/share/nginx/html": "${workspaceRoot}"
}
}
]
}
添加一些断点:
并在PhpStorm上执行以下操作:
使用docker compose的PhpStorm CLI解释器:
但是在开始监听PHP调试连接时我得到端口9009正忙
IDE从不启动调试工具=(我会错过什么?请帮帮我
在一些评论之后: 从
docker compose.yml
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#
但在开始监听PHP调试连接时,我得到的端口9009正忙
不需要在Docker容器中公开Xdebug端口,根本不需要
如果您公开它,.Docker将侦听该端口并将所有连接转发到容器中。但必须侦听它的是IDE/VSCode/PhpStorm…因为连接到IDE的是Xdebug,而不是其他方式
先把它修好
xdebug.remote\u connect\u back=1
我建议关闭此选项并在xdebug.remote\u host
(docker.for.mac.localhost
)中指定实际主机
Xdebug通过远程连接返回选项检测到的IP(取决于我猜的设置和Docker的工作方式)很可能不是主机的IP。但这正是您需要的——这是您的IDE(PhpStorm)/编辑器(VSCode)运行的地方,Xdebug必须连接到的地方。如果您使用的是“Docker for Mac”,则在xdebug配置文件中,也可以使用:
xdebug.remote_host = host.docker.internal
我想从容器连接到主机上的服务
主机的IP地址正在更改(如果您没有网络访问权限,则没有)。从18.03起,我们建议连接到特殊的DNS名称host.docker.internal,该名称解析为主机使用的内部IP地址。这是出于开发目的,在docker for Mac之外的生产环境中不起作用
网关也可以作为gateway.docker.internal访问。让XDEBUG工作就像一次让10个盘子在棍子上旋转一样。可能存在的一个问题是,PhpStorm无法看到它报告的PHP.ini文件。您在“语言和框架”部分配置过PHP吗?另外,您构建文档的唯一目的是什么您是否希望能够使用XDEBUG进行本地开发,或者出于其他原因对使用Docker感兴趣?瞧,其他已经使用XDEBUG的替代方案如何?@MikeSchinkel我添加了一个带有解释器信息的图像。“但是在开始监听PHP调试连接时,我发现端口9009正忙着
”当然,它很忙——你正在使用它。你在Docker中公开了9009?为什么?为什么?如果你公开了它。Docker侦听该端口并将所有连接转发到容器中。但是..必须侦听它的是IDE/VSCode/PhpStorm…因为连接到IDE的是Xdebug,而不是其他方式(请使用RTFM)。所以,请先解决这个问题,然后再试一次。@LazyOne Tks。所以我用您的建议更新了这个问题1)哪个应用程序在9009上侦听?在Mac上使用sudolsof-nP-iTCP-sTCP:LISTEN
,在Windows上使用netstat
。2) xdebug.remote\u connect\u back=1
--我最好关闭此选项,并在remote\u host
中指定主机--试试这种方法。Xdebug或nc每次尝试连接的IP地址都不一样--好吧,不应该是这样的。mac、windows和linux现在有一个通用设置,我认为是“host.docker.internal”,但如果没有您的第二部分响应,它就不起作用,也不是很重要,所以我在阅读中丢失了它,但是xdebug.remote\u connect\u back=0也非常重要!!!我只是阅读你的设置,而不是周围的文字,所以我认为它必须设置为1,但它必须为零。考虑到各种各样的家伙在玩端口映射和expose,正如您正确地说的那样是无用的,因为php中的xdebug内部使用随机隐藏端口,9000混凝土端口是远程端口。否则,感谢您的帮助。因此xdebug.remote\u connect\u back=0在windows上也是必需的,尽管在linux上我有过不需要禁用它的经验。