Docker PHP-FPM 8.1写入权限被拒问题求助
以下是针对你的权限异常问题的核心原因及对应解决方法:
构建阶段文件权限继承差异
Docker构建时,COPY/ADD指令会直接继承宿主机的文件权限。如果Ubuntu宿主机上的应用文件属于root:root,复制到容器后会保留该权限;而Manjaro宿主机上的文件权限是1000:1000,因此容器内权限一致。
解决方法:在Dockerfile中显式处理文件权限,二选一即可:# 方式1:先切换到创建的1000用户再复制文件 RUN useradd -u 1000 appuser USER appuser COPY ./app /var/www/html# 方式2:复制后修改文件所属用户 RUN useradd -u 1000 appuser COPY ./app /var/www/html RUN chown -R appuser:appuser /var/www/htmlDocker用户命名空间映射差异
Ubuntu默认启用了Docker的用户命名空间隔离功能,会将容器内的UID/GID映射到宿主机的非特权UID/GID范围。即便你在容器内指定UID 1000,实际对应宿主机的UID可能不是你的本地1000用户,导致挂载目录权限不匹配,写入操作失败。
解决方法:- 检查
/etc/docker/daemon.json,如果存在userns-remap配置项,将其注释后重启Docker:sudo systemctl restart docker - 若需要保留命名空间映射,可通过
docker inspect <容器名>查看UID映射关系,调整宿主机挂载目录的权限匹配映射后的UID/GID。
- 检查
AppArmor安全策略限制
Ubuntu默认启用AppArmor,Docker的默认安全策略可能限制容器内的文件写入操作,即便目录设置了chmod 775,PHP的is_writable()仍会返回false。
解决方法:- 临时关闭容器的AppArmor验证测试:
在docker-compose.yml中添加配置:services: php: security_opt: - apparmor:unconfined - 若测试有效,可创建自定义AppArmor profile,放宽对该容器的写入限制。
- 临时关闭容器的AppArmor验证测试:
docker-compose user参数生效时机问题
docker-compose中的user参数仅在容器启动时生效,构建阶段仍以root用户执行。如果构建时文件是root权限复制的,启动后切换到1000用户也无法修改已有文件的权限,导致写入失败。而Manjaro环境可能在构建阶段就切换了用户,或宿主机文件本身是1000权限,因此无此问题。
解决方法:确保Dockerfile中在复制文件前切换到目标用户,或复制后修改文件所属用户为1000:1000。
内容的提问来源于stack exchange,提问作者Zelf

