🚨【实战全记录】Docker 中 Nginx + PHP-FPM 跨容器 502 错误的极限排查全纪录
2025-03-27
502 是最讨人烦的服务端错误,特别是在 Docker 多容器环境中,Nginx + PHP-FPM 的 FastCGI 链路略有差错,就可能全线不通。
本文记录一个真实案例,6 个层级排查,最终破局,并提炼出适用于所有开发者的排查思路和配置策略。
👉 背景信息
容器 1:
nginx
(前端)容器 2:
php-fpm
(基于 Remi PHP 7.1)同一 Docker bridge 网络,可相互 DNS 识别
调用
/test.php
时一直报 502 Bad GatewayPHP 用
php -S
启动时可正常访问Nginx 访问静态文件正常,但访问 PHP 一定\u502
🔧 排查路线(按时间序排列)
第一步:基础信息确认
确认 PHP-FPM 已经启动,监听给 9000 端口
ss -tlnp | grep 9000
输出:
LISTEN 0.0.0.0:9000
等运行正常确认 nginx 容器可 curl / telnet 连接 php-fpm 容器
telnet docker_tj_pro_php_fpm_api_1 9000
可连通,但 curl 返回:
curl: (56) Recv failure: Connection reset by peer
第二步:Nginx 配置格式同步确认
fastcgi_pass
是启动于 PHP-FPM 容器的名称+9000 端口SCRIPT_FILENAME
重置为:fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
有数次试验指定绝对路径,但任何配置都 502
第三步:通过 cgi-fcgi 直接连接 PHP-FPM 验证
export SCRIPT_FILENAME=/data/tj-api/test.php export SCRIPT_NAME=/test.php export REQUEST_METHOD=GET cgi-fcgi -bind -connect docker_tj_pro_php_fpm_api_1:9000
结果:连接成功,无输出直接 Reset,确认是被 PHP-FPM 拒绝
🤔 真相大曝光:PHP-FPM 限制访问源
位于 /etc/opt/remi/php71/php-fpm.d/www.conf
配置文件中:
listen = 0.0.0.0:9000 listen.allowed_clients = 127.0.0.1
意思是:PHP-FPM 只允许 127.0.0.1 进行 FastCGI 连接
而 Docker bridge 网络下 Nginx 连 PHP-FPM 时使用的是 172.xx.xx.xx,实际上是被拒绝的
🔴 路径错误一:你许了 0.0.0.0
也不行
本场景中,你试图重置:
listen.allowed_clients = 0.0.0.0
但是任然被 Reset,502 不退
解释:PHP-FPM 中不支持 0.0.0.0 作为 allowed_clients!
它不是 "允许所有 IP" 的通配符,而是一个非法值
解决方式为:将该配置直接注释掉,就是允许全部连接
;listen.allowed_clients = 127.0.0.1
就可以解除网络限制,Nginx 容器可顺利连通
🚫 路径错误二:你以为你改了配置,其实没生效
本场景中最后确认:
因为 Docker 容器里的 PHP 配置文件没有接入 volume,每次重建容器都重置成默认值
解决方案:
要么每次重定义后构建镜像
要么直接 volume 挂载 PHP 的全部配置:
volumes: - ./php/php.ini:/etc/opt/remi/php71/php.ini - ./php/php-fpm.conf:/etc/opt/remi/php71/php-fpm.conf - ./php/www.conf:/etc/opt/remi/php71/php-fpm.d/www.conf
📊 结论性排查模型
排查步骤 | 要点确认 |
---|---|
网络通路 | curl / telnet 端口 |
FPM 是否监听 | ss -tlnp |
Nginx 同步参数 | SCRIPT_FILENAME 重构是否正确 |
FastCGI 直连测试 | cgi-fcgi |
有无连接限制 | listen.allowed_clients |
配置是否生效 | volume 挂载或自己建镜 |
🤖 返回到根本:对于 Docker 环境的 PHP-FPM 配置提示
你的给出的经验超值万重!请保持:
无论如何,如果是 Docker 环境:
注释掉
listen.allowed_clients
才是正确打开方式0.0.0.0
无效,不是通配符全部 PHP 配置都要进行 volume 挂载或写入 Dockerfile
不要仅仅修改容器内文件,重启后会被覆盖
by 楠哥 红尘炼心,知行一体。
发表评论: