Hyperf Docker 启动报 Permission denied 主因是 Swoole 进程用户与目录归属不匹配;需先查日志定位被拒路径(90%为 runtime/、storage/ 或 vendor/bin/hyperf.php),再用 ps aux | grep swoole 确认进程用户,接着 chown -R 用户:用户 runtime storage 并 chmod +x vendor/bin/hyperf.php。

Hyperf 在 Docker 容器中启动报 Permission denied,绝大多数情况不是框架问题,而是容器内用户与目录权限不匹配导致的。核心思路是:确认 Swoole 进程用谁跑、对应目录归谁所有、关键文件有没有执行权。
快速定位被拒路径
直接查看 Hyperf 启动日志里明确写出的错误路径,90% 集中在以下三处:
- runtime/(缓存、代理类、AOP 切面等运行时生成内容)
- storage/(日志、上传、临时文件等)
- vendor/bin/hyperf.php(入口脚本,必须可执行)
不要一上来就 chmod 777 整个项目——过度开放反而可能触发安全机制拦截,且掩盖真实归属问题。
确认 Swoole 进程实际运行用户
进入容器执行:
ps aux | grep -E 'swoole|hyperf'
观察输出中 USER 列,常见值有 www-data、nginx、app 或自定义 UID(如 82)。这个用户就是后续所有权限校验的基准。
若看到 root,说明容器没按预期降权运行,需检查 Dockerfile 或 docker-compose.yml 中是否漏了 USER 指令。
修复目录与文件归属及权限
在容器内依次执行(以 www-data 为例,按你上一步查到的实际用户调整):
- 重设 runtime 和 storage 目录属主:
chown -R www-data:www-data runtime storage - 确保 vendor/bin/hyperf.php 可执行:
chmod +x vendor/bin/hyperf.php - 清理残留只读缓存(尤其改过权限后仍报错时必做):
rm -rf runtime/*
目录建议权限为 755,普通文件为 644,够用且安全。
Docker 构建与挂载阶段预防措施
很多权限问题其实在构建阶段就埋下了:
- 避免在宿主机或容器内用
root执行composer install;推荐在 Dockerfile 多阶段构建中,显式切换用户安装:RUN sudo -u www-data composer install --no-dev --optimize-autoloader - 开发时慎用 bind mount 整个项目目录;
应只挂载源码和配置,避开 runtime/storage:volumes: ["./app:/app/app", "./config:/app/config:ro"] - 在 docker-compose.yml 中显式声明用户,避免依赖默认 UID 映射:
user: "82:82"(对应 www-data 的 UID/GID)
构建完成后可验证 vendor 权限:docker run --rm -it your-image ls -l vendor/bin/hyperf.php,确认属主正确且有 x 权限。


















