无尘阁日记

无尘阁日记

🚨【实战全记录】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 Gateway

  • PHP 用 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 楠哥 红尘炼心,知行一体。