Hyperf 镜像体积大源于构建时混入编译工具链,多阶段构建可将体积从700MB+压至80MB左右;需严格分离builder(编译Swoole)和runner(仅运行)阶段,精确复制swoole.so及配置文件,并彻底清理builder缓存。

Hyperf 镜像体积大,不是因为框架本身重,而是构建时把 PHP 编译器、Swoole 源码、pecl 工具链、apt 缓存、临时依赖全塞进最终镜像了。用多阶段构建能直接砍掉 80% 以上体积——比如从 700MB+ 压到 80MB 左右,且不牺牲运行稳定性。
Hyperf 多阶段构建必须分清 builder 和 runner 两个阶段
builder 阶段负责编译 Swoole 扩展、安装 PHP 依赖;runner 阶段只保留运行必需的 PHP 运行时、已编译好的 swoole.so 和应用代码。两个阶段不能混用同一基础镜像,否则就退化成单阶段。
- builder 阶段推荐用
php:8.1-cli(非 Alpine):确保pecl install swoole能顺利编译,避免 musl libc 兼容问题 - runner 阶段优先选
php:8.1-cli-slim:体积小(约 65MB)、glibc 兼容、无冗余工具,比 Alpine 更稳 - 绝对不要在 runner 阶段
RUN apt-get install或pecl install:这会让构建工具链重新进入最终镜像
COPY --from=builder 必须精确复制,别漏关键文件
多阶段构建失效的常见原因是 COPY --from=builder 只复制了代码,却忘了 Swoole 扩展文件或配置。Hyperf 启动失败报 Class swoole_http_server not found,基本就是这个原因。
- builder 阶段编译完 Swoole 后,要显式启用并确认路径:
RUN docker-php-ext-enable swoole && ls /usr/local/lib/php/extensions/*/swoole.so - runner 阶段需复制两处:
COPY --from=builder /usr/local/lib/php/extensions/*/swoole.so /usr/local/lib/php/extensions/和COPY --from=builder /usr/local/etc/php/conf.d/docker-php-ext-swoole.ini /usr/local/etc/php/conf.d/ - 应用代码建议用
COPY --chown=www-data:www-data . /var/www/html/,避免权限问题导致 Hyperf 启动卡住
builder 阶段清理要彻底,否则缓存会污染 runner
builder 阶段装的 build-essential、autoconf、g++ 等包,哪怕没被复制到 runner,只要它们存在于 builder 镜像层里,就可能因 Docker 构建缓存机制被意外继承——尤其当你改了 RUN 顺序又没加 --no-cache 时。
- builder 阶段末尾必须清理:
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* - 禁用构建缓存调试时,用
docker build --no-cache --target builder -t hyperf:build .单独验证 builder 输出是否干净 - 如果项目用了 Composer 的
install --no-dev,务必放在COPY . .之后、RUN composer install之前,否则 dev 依赖仍会进 vendor
最易被忽略的是 php.ini 中的 extension_dir 路径和扩展加载顺序。多阶段下,runner 阶段的 extension 目录可能和 builder 不一致,硬编码路径会导致 swoole.so 找不到——别写死路径,用 docker-php-ext-enable 自动生成配置才是可靠做法。


















