Docker部署PHP+Nginx时容器连接失败upstream报错解决方案
故障根因
两个核心问题导致报错:
- PHP镜像选型错误:使用的
php:latest是CLI命令行版本镜像,默认启动命令是交互式PHP Shell,没有常驻运行的php-fpm服务,容器启动后没有前台进程会直接以状态码0退出,此时Docker内部DNS不存在php对应的主机记录 - 服务启动顺序无可靠保障:使用过时的
links配置不会等待PHP服务完全就绪就启动Nginx,就算PHP容器正常运行,也可能出现Nginx启动时DNS还未同步完成的解析失败问题
排查步骤
- 执行
docker-compose ps查看容器状态,可发现PHP容器状态为Exited (0),未正常常驻运行 - 执行
docker-compose logs php查看PHP容器启动日志,可看到输出Interactive shell后直接退出,确认镜像启动命令不符合fpm服务要求 - 修正PHP镜像后,进入Nginx容器执行
getent hosts php验证DNS解析是否正常,返回PHP容器IP即代表网络连通正常 - 配置服务重启策略,解决偶发的启动顺序导致的解析失败问题
修正后的配置
- 修改
docker/php/Dockerfile,替换为带fpm服务的官方镜像:
# 选用fpm变体镜像,默认启动php-fpm进程常驻,监听9000端口 FROM php:fpm
- 修改
docker-compose.yml,移除过时配置,调整依赖和端口映射:
version: "3.8" services: nginx: container_name: nginx build: ./docker/nginx ports: - "80:80" volumes: - ./src:/var/www/html depends_on: - php # 启动失败自动重试,规避偶发的DNS未同步问题 restart: on-failure php: container_name: php build: ./docker/php volumes: - ./src:/var/www/html working_dir: /var/www/html
说明:同Compose项目下的服务默认加入同一个桥接网络,服务名可直接作为域名解析,不需要额外配置
links;PHP的9000端口仅需对内网服务开放,不需要映射到宿主机,减少不必要的端口暴露。
- 原有
default.conf配置无需修改,fastcgi_pass php:9000的写法在网络正常时可直接解析。
启动验证
执行以下命令清理旧资源并重新启动:
docker-compose down -v --rmi local docker-compose up -d --build
启动完成后执行docker-compose ps,确认两个容器均为Up状态,访问本地80端口即可正常看到phpinfo输出页面。
内容的提问来源于stack exchange,提问作者Prof Nami
相关产品推荐
相关产品推荐

