Dockerfile无法同时启动NGINX与PHP的问题求助
解决Docker容器中同时启动Nginx和PHP-FPM的问题
我帮你梳理下问题的核心:Docker容器默认只会维持一个前台运行的主进程,如果你的命令是后台运行的,或者只执行了第一个命令,容器就会因为主进程退出而停止。你之前试的CMD数组(比如CMD ["nginx", "php-fpm7.0"])只会执行第一个命令nginx,后面的php-fpm7.0根本不会运行;而普通的shell脚本如果没让进程前台运行,脚本执行完所有命令后就会退出,容器也跟着停了。
下面给你两种可靠的解决方案,按推荐程度排序:
方案一:用Supervisor管理多进程(推荐)
Supervisor是专门用来管理Linux进程的工具,能帮你同时启动、监控Nginx和PHP-FPM,而且进程挂了会自动重启,非常适合Docker场景。
完整Dockerfile示例
FROM ubuntu:16.04 WORKDIR /opt/ # 安装依赖+Supervisor,同时清理缓存减小镜像体积 RUN apt-get update && apt-get install -y \ nginx=1.10.* \ php7.0 php7.0-fpm php7.0-mysql \ supervisor \ && rm -rf /var/lib/apt/lists/* # 替换成你的自定义Nginx配置(这里保留你原有步骤,比如删除默认配置) RUN rm -f /etc/nginx/sites-enabled/default # 如果你有自定义配置文件,加上这行:COPY ./your-nginx-config.conf /etc/nginx/sites-available/ # RUN ln -s /etc/nginx/sites-available/your-nginx-config.conf /etc/nginx/sites-enabled/ # 配置Supervisor的日志目录 RUN mkdir -p /var/log/supervisor # 复制Supervisor配置文件(需要你单独创建这个文件) COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf # 启动Supervisor(它会作为容器的主进程) CMD ["/usr/bin/supervisord"]
对应的supervisord.conf配置文件
创建这个文件放在和Dockerfile同目录下:
[supervisord] nodaemon=true # 让Supervisor前台运行,作为容器主进程 [program:nginx] command=/usr/sbin/nginx -g "daemon off;" # 强制Nginx前台运行 autostart=true autorestart=true stdout_logfile=/var/log/supervisor/nginx.log stderr_logfile=/var/log/supervisor/nginx.err [program:php-fpm] command=/usr/sbin/php-fpm7.0 -F # -F参数让PHP-FPM前台运行 autostart=true autorestart=true stdout_logfile=/var/log/supervisor/php-fpm.log stderr_logfile=/var/log/supervisor/php-fpm.err
方案二:用Shell脚本启动(轻量但监控弱)
如果不想额外安装Supervisor,可以写一个启动脚本,让PHP-FPM后台运行,Nginx前台运行(作为容器主进程)。
启动脚本start.sh
#!/bin/bash # 启动PHP-FPM并后台运行 php-fpm7.0 -F & # 启动Nginx前台运行(这会成为容器的主进程) nginx -g "daemon off;"
修改Dockerfile添加脚本
在Dockerfile末尾加上:
# 复制启动脚本并赋予执行权限 COPY start.sh /opt/start.sh RUN chmod +x /opt/start.sh # 执行启动脚本 CMD ["/opt/start.sh"]
注意事项
- 这种方式下,如果PHP-FPM意外挂了,容器不会自动重启它,所以生产环境更推荐方案一。
- 确保你的Nginx配置正确指向PHP-FPM,比如在server块里配置:
location ~ \.php$ { fastcgi_pass unix:/run/php/php7.0-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }
内容的提问来源于stack exchange,提问作者Nicolas El Khoury
相关产品推荐
相关产品推荐

