Docker容器运行PHP应用时出现503 Service Unavailable错误排查求助
咱们一步步拆解问题,先从最可能的原因入手:
1. 优先排查文件权限问题
你通过ADD指令把index.php放到/var/www/html/后,这个文件的默认权限是root:root,但CentOS里的httpd默认是以apache用户身份运行的——这就可能导致httpd进程没有读取该文件的权限,直接触发503错误。
手动执行命令时你没遇到这个问题,大概率是因为你全程用root操作,临时权限覆盖了这个问题;但镜像构建后容器内的httpd是用apache用户跑的,权限限制就暴露出来了。
验证方法:进入容器后执行:
ls -l /var/www/html/index.php
如果输出是类似-rw-r--r-- 1 root root ...,那就是权限问题无疑了。
解决方法:在Dockerfile里添加修改权限的指令:
FROM centos:latest RUN yum install net-tools httpd php -y ENV REFRESHED_AT "04-06-2016" ADD index.php /var/www/html/ # 修改文件归属为apache用户,确保服务能读取 RUN chown apache:apache /var/www/html/index.php
2. 查看httpd错误日志定位深层问题
如果权限没问题,直接查看httpd的错误日志能快速找到根因:
cat /var/log/httpd/error_log
比如日志里如果出现Cannot load ... php_module into server,说明PHP模块加载失败;如果是路径错误、配置语法问题也会有明确提示。
3. 顺便解决ServerName警告&优化容器启动方式
你遇到的Could not reliably determine the server's fully qualified domain name警告,可以通过添加一行配置解决:
# 在Dockerfile里添加ServerName配置消除警告 RUN echo "ServerName localhost" >> /etc/httpd/conf/httpd.conf
另外,容器运行时建议让httpd前台运行(否则容器会因为没有前台进程直接退出),可以直接用以下命令启动容器,不用手动进入启动服务:
docker container run -it --name os1 -p 8080:80 myimage /usr/sbin/httpd -D FOREGROUND
这样还能把容器的80端口映射到主机的8080,直接用curl localhost:8080就能访问测试。
为什么手动执行没问题?
手动操作时你是在root会话里完成所有步骤,启动httpd后,临时权限可能让apache进程能读取root归属的文件;或者你手动操作时无意中修改了权限但自己没留意。而镜像构建是完全自动化的流程,权限限制就被明确触发了。
内容的提问来源于stack exchange,提问作者keshav swami

