Docker部署Laravel报错laravel.log无法追加打开 权限被拒如何解决
你遇到的反复复现的权限问题,本质是只修改了storage根目录权限,没有对齐Docker容器内进程运行身份、挂载规则、子文件/目录的权限要求,且手动在运行容器内修改的临时权限会在容器重启/重建后重置,才会出现偶发自愈后又故障的情况。
修复步骤
确认容器内Web进程实际运行用户
不要默认所有PHP镜像的运行用户都是www-data,先进入Laravel所在的应用容器,执行命令查看工作进程身份:ps aux | grep -E 'php-fpm|nginx' | grep -v grep输出第一列就是进程运行用户,部分自定义镜像会用
apache、nginx或自定义uid的用户,后续权限替换为对应的用户和用户组即可。递归修正所有可写目录权限
你当前仅改了storage根目录,其下子目录、历史日志文件(尤其是之前用root执行artisan命令生成的laravel.log,属主为root时普通用户无法写入)、以及Laravel必须可写的bootstrap/cache目录都可能存在权限错配,在容器内项目根目录执行:# 把www-data:www-data替换为上一步查到的实际运行用户:组 chown -R www-data:www-data storage/ bootstrap/cache/ chmod -R 775 storage/ bootstrap/cache/如果执行后仍报错,直接删除旧的
storage/logs/laravel.log,Laravel会自动生成权限匹配的新日志文件。修复SELinux挂载限制(宿主机为CentOS/RHEL/Fedora等开启SELinux的系统必做)
这是Docker绑定挂载场景下权限时好时坏的最常见隐性原因,SELinux默认会拦截容器对宿主机挂载目录的写入,需要在挂载配置中加SELinux共享标签:docker run启动时,挂载参数后追加:z:docker run -v /本地项目路径:/var/www/html:z ......- docker-compose启动时,volume配置后追加
:z标签:services: php: volumes: - ./:/var/www/html:z
不要使用大写
:Z标签,该标签会将目录标记为单个容器私有,多容器共享挂载时会触发新的权限冲突。永久解决容器重启后权限重置问题
运行中容器内手动修改的权限会在容器重建/重启后失效,这也是问题反复复现的核心原因,二选一配置即可:- 在Dockerfile中构建阶段预置正确权限,拷贝代码后追加以下逻辑:
COPY . /var/www/html # 替换为实际运行用户:组 RUN chown -R www-data:www-data /var/www/html/storage /var/www/html/bootstrap/cache \ && chmod -R 775 /var/www/html/storage /var/www/html/bootstrap/cache - 在容器启动命令中加入权限初始化逻辑,服务启动前自动修正权限,以PHP-FPM为例:
CMD ["sh", "-c", "chown -R www-data:www-data storage bootstrap/cache && chmod -R 775 storage bootstrap/cache && php-fpm"]
- 在Dockerfile中构建阶段预置正确权限,拷贝代码后追加以下逻辑:
内容的提问来源于stack exchange,提问作者Daniel L

