Docker容器中PHP file_put_contents无法写入Ubuntu宿主机的权限问题
Docker部署PHP应用的权限问题排查与解决
问题背景
我正在学习用Docker部署PHP应用,写了个简单的index.php,想用file_put_contents往Ubuntu宿主机的test.txt写入‘hello world’,但一直碰到权限问题。
初始配置文件
三个核心文件内容如下:
# ~/docker/docker-compose.yml version: "3.8" services: website: container_name: website build: context: ./ dockerfile: Dockerfile ports: - "80:80" volumes: - ../public_html:/var/www/html logging: options: max-file: "10" max-size: 10m
# ~/docker/Dockerfile FROM php:5.4-apache RUN chown -R www-data:www-data /var/www/html CMD ["/usr/sbin/apachectl", "-D", "FOREGROUND"]
// ~/public_html/index.php <?php file_put_contents('test.txt', 'hello world');
执行的启动命令
用户john拥有sudo权限,执行了以下命令:
john@localhost: sudo su root@localhost: systemctl start docker root@localhost: exit john@localhost: sudo chown -R john:john ~/docker john@localhost: sudo chown -R john:john ~/public_html john@localhost: sudo chmod -R 755 ~/public_html john@localhost: cd ~/docker john@localhost: sudo docker-compose up --build -d;
初始错误
访问http://192.168.0.10/index.php时出现错误:
Warning: file_put_contents(test.txt): failed to open stream: Permission denied in /var/www/html/index.php on line 1
手动在宿主机执行touch ~/public_html/test.txt && chmod 777 ~/public_html/test.txt能临时解决,但我想保持权限为755。
尝试UID对齐后的问题
了解到要对齐宿主机和容器的用户ID(UID),于是添加了.env文件设置CURRENT_UID=1000(通过id -u查到john的UID是1000),并修改了docker-compose.yml和Dockerfile:
# ~/docker/.env CURRENT_UID=1000
# ~/docker/docker-compose.yml version: "3.8" services: website: container_name: website user: ${CURRENT_UID} environment: CURRENT_UID: ${CURRENT_UID} build: context: ./ dockerfile: Dockerfile ports: - "80:80" volumes: - ../public_html:/var/www/html logging: options: max-file: "10" max-size: 10m
# ~/docker/Dockerfile FROM php:5.4-apache USER ${CURRENT_UID}:${CURRENT_UID} RUN chown -R ${CURRENT_UID}:${CURRENT_UID} /var/www/html RUN chown -R ${CURRENT_UID}:${CURRENT_UID} /etc/apache2 RUN chown -R ${CURRENT_UID}:${CURRENT_UID} /var/log/apache2 RUN chown -R ${CURRENT_UID}:${CURRENT_UID} /var/run/apache2 CMD ["/usr/sbin/apachectl", "-D", "FOREGROUND"]
修改后容器无法启动,查看docker logs website显示:
[Wed Jun 28 23:01:18.623744 2023] [core:error] [pid 7] (13)Permission denied: AH00099: could not create /var/run/apache2/apache2.pid [Wed Jun 28 23:01:18.623918 2023] [core:error] [pid 7] AH00100: apache2: could not log pid to file /var/run/apache2/apache2.pid Action '-D FOREGROUND' failed. The Apache error log may have more information
用户疑问
- 我哪里操作有误?
- 容器启动失败后如何查看Apache错误日志?
问题排查与解决方案
1. 操作错误分析
核心问题出在镜像构建阶段环境变量未定义和错误切换用户修改系统目录权限:
- Dockerfile构建时,
${CURRENT_UID}是在docker-compose运行阶段注入的变量,构建镜像时根本不存在,导致USER ${CURRENT_UID}:${CURRENT_UID}执行失败,后续RUN chown命令也无法按预期生效。 - Apache依赖
www-data系统用户运行,直接切换到宿主机UID用户,该用户在容器内可能不存在,且就算存在,也没有权限操作Apache的系统目录(如/var/run/apache2、/etc/apache2),这些目录默认属于www-data或root用户。
2. 正确的权限对齐方案
不需要切换容器运行用户,而是把容器内的www-data用户UID改成和宿主机john用户一致(即1000):
修改后的Dockerfile
FROM php:5.4-apache # 将容器内www-data用户的UID/GID改为宿主机用户的UID/GID ARG CURRENT_UID RUN usermod -u ${CURRENT_UID} www-data && groupmod -g ${CURRENT_UID} www-data # 确保网站目录权限正确 RUN chown -R www-data:www-data /var/www/html CMD ["/usr/sbin/apachectl", "-D", "FOREGROUND"]
修改后的docker-compose.yml
version: "3.8" services: website: container_name: website build: context: ./ dockerfile: Dockerfile args: CURRENT_UID: ${CURRENT_UID} # 将环境变量传递到构建阶段 ports: - "80:80" volumes: - ../public_html:/var/www/html logging: options: max-file: "10" max-size: 10m
.env文件保持不变
CURRENT_UID=1000
宿主机权限调整
确保宿主机public_html目录属于UID 1000(john用户),权限保持755即可:
sudo chown -R john:john ~/public_html sudo chmod -R 755 ~/public_html
这样容器内的www-data用户UID与宿主机john一致,既能正常读写挂载目录文件,Apache也能以默认的www-data用户正常运行,不会出现系统目录权限问题。
3. 容器启动失败后查看Apache日志的方法
- 容器未完全退出时:执行
docker exec -it website /bin/bash进入容器,查看默认错误日志:cat /var/log/apache2/error.log - 容器已退出时:在docker-compose.yml中添加日志目录挂载,把容器内的Apache日志同步到宿主机:
之后可以直接在宿主机volumes: - ../public_html:/var/www/html - ../apache_logs:/var/log/apache2 # 新增日志挂载~/apache_logs/error.log查看日志,即使容器启动失败也能获取完整日志。 - 直接查看容器日志:
docker logs website会输出容器的标准输出/错误,大部分Apache启动错误都会在这里显示,比如你之前看到的pid文件创建失败日志。
内容的提问来源于stack exchange,提问作者learningtech
相关产品推荐
相关产品推荐

