Laravel Docker镜像无法修改/var/www/storage/logs权限,始终为root所有
问题描述
使用指定Dockerfile构建PHP 8.1.0-fpm镜像部署Laravel项目后,/var/www/storage/logs/laravel.log始终为root权限,导致Postman发起请求时出现如下权限拒绝错误:
The stream or file "/var/www/storage/logs/laravel.log" could not be opened in append mode: Failed to open stream: Permission denied
The exception occurred while attempting to log: The stream or file "/var/www/storage/logs/laravel.log" could not be opened in append mode: Failed to open stream: Permission denied
手动执行sudo chmod -R ugo+rw storage无法解决问题,日志文件权限仍保持root。
原因分析
- 镜像构建阶段,
composer update、composer install等命令以root用户执行,若过程中Laravel生成日志文件,该文件会被标记为root权限。 - 容器启动后,PHP-FPM或Nginx进程以root用户运行,后续写入日志时仍使用root权限,覆盖手动修改的权限设置。
解决方案
1. 切换用户执行Composer命令
在Dockerfile中,使用www用户执行Composer相关操作,避免生成root权限的文件:
# 替换原Deployment steps部分 # Deployment steps RUN su www -c "composer update" RUN su www -c "composer install --optimize-autoloader --no-dev" RUN chmod +x /var/www/docker/run.sh
2. 提前配置日志目录权限
在Dockerfile中提前创建日志目录并设置归属,避免首次生成文件时权限错误:
# 在Copy code步骤后添加 RUN mkdir -p /var/www/storage/logs && chown -R www:www-data /var/www/storage/logs
3. 以www用户启动服务
修改docker/run.sh脚本,切换到www用户启动PHP-FPM和Nginx,确保日志写入进程为非root用户:
#!/bin/bash # 确保storage目录权限正确 chown -R www:www-data /var/www/storage # 切换到www用户启动服务 exec su www -c " php-fpm & nginx -g 'daemon off;' "
4. 调整PHP-FPM配置(可选)
确保PHP-FPM的www.conf配置文件中,用户和组设置为www:
user = www group = www
可在Dockerfile中添加复制配置的命令:
RUN cp docker/www.conf /usr/local/etc/php-fpm.d/www.conf
验证方法
重新构建镜像并启动容器,进入容器查看日志文件权限:
docker exec -it <容器ID> ls -l /var/www/storage/logs/laravel.log
输出应为www用户和组权限,此时发起请求不再出现权限错误。
内容的提问来源于stack exchange,提问作者FreddicMatters

