hyperf用docker-compose启动核心是镜像构建正确且容器按序运行;需用含swoole的官方镜像、cmd数组格式执行php bin/hyperf.php start、ports映射对齐、禁用冲突volumes,并配置restart: unless-stopped保障服务常驻。

Hyperf 项目用 docker-compose 启动,核心就两步:镜像得构建好、容器得按正确顺序跑起来。如果启动失败,90% 是 Dockerfile 没写对或 docker-compose.yml 的挂载/端口/启动命令有冲突。
docker-compose up -d 之前必须确保 build 成功
很多人直接 docker-compose up -d 报错,比如 ERROR: failed to solve: failed to read dockerfile 或 command not found: php,本质是构建阶段就断了。
-
Dockerfile第一行必须用带 Swoole 的官方镜像,例如FROM hyperf/hyperf:8.2-alpine-v3.18-swoole;用纯php:8.2-cli镜像会缺swoole扩展,hyperf.php start直接退出 - 执行
composer create-project必须在RUN指令里完成,不能靠volumes挂载宿主机空目录进去——否则容器一启动就发现bin/hyperf.php不存在,CMD失败 - 构建时加
--no-interaction --prefer-dist参数,避免交互卡住;国内环境务必配阿里云 Composer 镜像,否则拉包超时导致构建中断
docker-compose.yml 的 ports 和 CMD 要对齐
Hyperf 默认监听 0.0.0.0:9501,但容器内端口暴露和宿主机映射不一致,就会出现「容器运行中但 curl 不通」。
-
EXPOSE 9501在Dockerfile里只是声明,真正生效靠docker-compose.yml的ports字段,必须写成- "9501:9501",不能只写一个端口 -
CMD ["php", "bin/hyperf.php", "start"]是最终入口,不要被entrypoint覆盖;如果docker-compose.yml里写了entrypoint,又没显式调用hyperf.php start,服务就不会真正启动 - 生产环境建议加
restart: unless-stopped,避免容器异常退出后服务静默挂掉
挂载 volumes 时机不对会导致项目启动失败
本地开发想热更新代码,但直接挂载空目录到 /home/carver-hyperf,容器启动时会清空整个工作目录——vendor、bin 全没了,php bin/hyperf.php start 必然报错。
- 首次构建镜像时先注释掉
volumes,让composer create-project在镜像内完整生成项目结构 - 等第一次
docker-compose up -d成功后,再用docker cp把容器内项目拷出来:docker cp carver-hyperf:/home/carver-hyperf ./data - 确认
./data里有bin/、config/、vendor/后,再取消volumes注释并指向该目录
最常被忽略的是:Hyperf 容器启动后,php bin/hyperf.php start 进程必须持续运行,不能是 shell 脚本执行完就退出。所以 CMD 必须是数组格式,不能写成 CMD php bin/hyperf.php start(shell 格式会被当作单条命令,Swoole 进程无法接管信号)。











