FrankenPHP 1.5 Docker 部署文件权限问题核心是容器用户(如 www-data,UID 33)与宿主机挂载目录 UID/GID 不匹配或目录缺 x 权限,导致上传、日志、缓存等静默失败;需统一 UID/GID、设目录 755 权限、显式配置 upload_tmp_dir 和 logs.output 绝对路径,并注意 SELinux/:z 标签及只读限制。

FrankenPHP 1.5 在 Docker 中部署时出现文件权限问题,核心在于容器内运行用户(如 www-data)与宿主机挂载目录的 UID/GID 不匹配,或目录本身缺少必要权限位(如 x 权限),导致 move_uploaded_file()、日志写入、缓存生成等操作静默失败或报 Permission denied。
确认并统一 UID/GID
Docker 默认镜像(如 dunglas/frankenphp)中 www-data 用户 UID 通常为 33。若宿主机挂载目录(如 ./public/uploads 或 ./storage)由 UID 1000 的用户创建,容器内进程就无权写入:
- 查宿主机 UID:
id -u(常见为 1000) - 在
docker-compose.yml中传入构建参数:build:<br> args:<br> UID: 1000
- 自定义 Dockerfile 中重设用户:
RUN usermod -u ${UID} www-data &&<br> groupmod -g ${UID} www-data
正确设置挂载目录权限
权限 ≠ 仅改文件,关键在目录的属主 + 执行位(x):
- 宿主机上初始化目录:
mkdir -p public/uploads storage/logs - 设属主(匹配容器内 UID):
sudo chown -R 33:33 public/uploads storage(若已统一 UID 为 1000,则用 1000) - 设目录权限为
755(确保www-data可进入、读取、执行):chmod 755 public/uploads storage - 避免
chmod -R 777:开放过大,存在安全风险
显式配置 upload_tmp_dir 和日志路径
FrankenPHP 不自动创建临时目录或日志目录,且默认用系统 /tmp —— 容器中该路径可能被隔离或权限受限:
立即学习“PHP免费学习笔记(深入)”;
- 在
php.ini(或通过frankenphp --php-ini指定)中设置:upload_tmp_dir = "/tmp/frankenphp" - 在容器启动前创建该目录并赋权:
RUN mkdir -p /tmp/frankenphp && chown www-data:www-data /tmp/frankenphp - 日志路径必须是绝对路径,且在
frankenphp.yaml中明确声明:logs:<br> output: "/var/log/frankenphp/access.log"
再确保/var/log/frankenphp目录存在、属主为www-data、权限为755
检查容器运行时限制
Docker 默认启用某些安全机制,会主动封锁写入行为:
- 若使用
docker run --read-only或read_only: true,需对特定路径加--tmpfs或tmpfs:挂载(如/tmp、/var/log) - SELinux 启用时(如 CentOS 宿主机),添加
:z标签挂载:-v $(pwd)/logs:/var/log/frankenphp:z - Rootless Docker 场景下,确保挂载路径对非 root 用户可访问,避免
userns-remap导致 UID 偏移



















