Nginx与PHP-FPM Docker容器连接失败排查求助
首先咱们直接定位核心问题:你在Nginx的default.conf里配置的fastcgi_pass 127.0.0.1:9000;,在Docker本地环境里是无效的——因为每个Docker容器都有独立的网络命名空间,127.0.0.1对于Nginx容器来说,指向的是它自己,而不是你运行的PHP-FPM容器。这也是为什么AWS ECS/Fargate上能正常运行(同一任务内容器共享网络空间),但本地不行的原因。
步骤1:修正Nginx的fastcgi_pass配置
把default.conf里的fastcgi_pass改成你通过--link设置的容器别名php:9000:
location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; # 替换原127.0.0.1:9000为容器别名php:9000 fastcgi_pass php:9000; error_log /var/log/nginx/error.log debug; access_log /var/log/nginx/access.log; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; }
解释:你用docker run --link php:php把PHP容器链接到Nginx容器时,Docker会自动在Nginx容器的/etc/hosts里添加一条记录,把php指向PHP容器的实际IP,所以用php:9000就能正确访问到PHP-FPM服务。
步骤2:正确验证Nginx配置文件
你之前执行nginx -t -c conf.d/default.conf报错,是因为conf.d/default.conf里的server指令不能直接作为主配置文件使用——主配置文件需要包含http块,而conf.d下的文件是被主配置/etc/nginx/nginx.conf里的include /etc/nginx/conf.d/*.conf;引入到http块中的。正确的配置测试命令应该是:
# 进入Nginx容器后执行 nginx -t
这样会加载完整的主配置,包含你自定义的default.conf,就能正常验证配置合法性了。
步骤3:确认PHP-FPM的监听配置(无需修改)
你提到PHP-FPM的zz-docker.conf里listen = 9000,这个配置是监听所有网卡的端口(相当于0.0.0.0:9000),完全符合跨容器访问的需求,不需要添加listen.allowed_clients限制——Docker链接的容器之间网络互通,只要PHP-FPM不限制仅本地访问就没问题,这也是AWS环境能正常运行的原因。
步骤4:重新构建并运行容器
修改完Nginx配置后,重新构建镜像并启动容器:
docker build -t nginx-aws-image -f docker/nginx/aws/Dockerfile . docker stop nginx && docker rm nginx docker run --link php:php --publish 8000:80 --name nginx nginx-aws-image
现在访问http://127.0.0.1:8000/health-check.php应该就能正常响应了。
内容的提问来源于stack exchange,提问作者Jaijaz

