Docker环境PHP-FPM 502 Bad Gateway错误排查求助
问题与解决方案
问题概况
基于nginx:alpine和php:fpm-alpine搭建容器服务,初次启动时Nginx与PHP通过内部网桥正常通信;但保存镜像并使用新的docker-compose-save.yml重新运行后,访问页面出现502 Bad Gateway错误。排查发现PHP容器中无PHP-FPM服务运行,php、php-fpm命令均不存在,容器反而监听80端口(Nginx默认端口)。
相关配置
初始docker-compose.yml
version: "3" services: nginx: build: context: . dockerfile: nginx/Dockerfile ports: - "8080:80" networks: - internal volumes: - ./data/:/var/www/html/ - ./logs/nginx:/var/log/nginx/ php: image: php:fpm-alpine networks: - internal volumes: - ./data/:/var/www/html/ - ./logs/php.log:/var/log/fpm-php.www.log networks: internal: driver: bridge
Nginx default.conf
server { listen 0.0.0.0:80; root /var/www/html; location / { index index.php index.html; } location ~ \.php$ { include fastcgi_params; fastcgi_pass php:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name; } }
重新加载用的docker-compose-save.yml
version: "3" services: nginx: image: php_with_nginx_nginx:latest ports: - "8080:80" networks: - internal volumes: - ./data/:/var/www/html/ - ./logs/nginx:/var/log/nginx/ php: image: phpnginxload:latest networks: - internal volumes: - ./data/:/var/www/html/ - ./logs/php.log:/var/log/fpm-php.www.log ports: - "9000:9000" networks: internal: driver: bridge
容器异常状态
7020:~/php_with_nginx$ docker exec -it php_with_nginx_php_1 sh / # netstat -tuln Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN tcp 0 0 127.0.0.11:38961 0.0.0.0:* LISTEN udp 0 0 127.0.0.11:33901 0.0.0.0:*
/usr/sbin # php-fpm -F sh: php-fpm: not found /usr/sbin # php -v sh: php: not found /usr/sbin #
核心原因
你保存的phpnginxload:latest镜像并非基于php:fpm-alpine,大概率是误提交了Nginx容器或空容器作为PHP镜像——从容器监听80端口可佐证这一点,这直接导致容器启动后没有PHP相关服务。
排查方向
验证镜像合法性:
- 执行
docker images查看phpnginxload:latest的基础镜像ID,与php:fpm-alpine对比 - 执行
docker history phpnginxload:latest查看镜像构建历史,确认是否包含PHP相关层
- 执行
检查镜像保存操作:
- 确认初次运行时,你是否正确选择了PHP容器进行
docker commit操作,而非Nginx容器
- 确认初次运行时,你是否正确选择了PHP容器进行
解决方案
1. 重新生成正确的PHP镜像
- 停止并清理错误资源:
docker-compose -f docker-compose-save.yml down docker rmi phpnginxload:latest - 启动初始服务获取正确的PHP容器:
docker-compose up -d - 找到PHP容器ID并提交为镜像:
# 查看运行中的容器,找到PHP容器ID docker ps # 提交镜像,替换<php_container_id>为实际ID docker commit <php_container_id> phpnginxload:latest
2. 改用Dockerfile构建镜像(推荐)
手动docker commit容器易出错,建议编写Dockerfile确保镜像可重复构建:
- 在项目根目录创建
php/Dockerfile:FROM php:fpm-alpine # 按需添加PHP扩展,例如安装pdo_mysql: # RUN docker-php-ext-install pdo_mysql - 修改初始
docker-compose.yml,让PHP服务从Dockerfile构建:version: "3" services: nginx: build: context: . dockerfile: nginx/Dockerfile ports: - "8080:80" networks: - internal volumes: - ./data/:/var/www/html/ - ./logs/nginx:/var/log/nginx/ php: build: context: . dockerfile: php/Dockerfile networks: - internal volumes: - ./data/:/var/www/html/ - ./logs/php.log:/var/log/fpm-php.www.log networks: internal: driver: bridge - 构建并标记镜像:
docker-compose build php docker tag php_with_nginx_php:latest phpnginxload:latest
3. 验证修复效果
启动服务后,进入PHP容器检查:
docker exec -it <php_container_name> sh # 检查9000端口是否监听 netstat -tuln | grep 9000 # 验证PHP命令是否存在 php -v
内容的提问来源于stack exchange,提问作者Vishy
相关产品推荐
相关产品推荐

