ThinkPHP 5.1 项目 Docker 镜像瘦身指南:极简

作者:袖梨 2026-07-14
根本原因是默认构建将开发依赖、调试工具和完整PHP运行时全塞入生产镜像;应采用多阶段构建:第一阶段用php:7.4-cli安装Composer及依赖并清理.git/tests/docs;第二阶段基于php:7.4-alpine仅复制vendor/application/public等必要文件,禁用Xdebug、启用OPcache,并用.dockeringore排除冗余文件,最后用Dive分析镜像层定位大文件。

你的 ThinkPHP 5.1 项目 Docker 镜像体积突破 400MB,构建慢、拉取卡顿、CI 流水线频繁超时,根本原因不是框架本身臃肿,而是默认构建方式把开发期依赖、调试工具、完整 PHP 运行时全塞进了生产镜像。

用多阶段构建剥离编译与运行环境

第一步:在 Dockerfile 开头添加 builder 阶段,基于 php:7.4-cli(非 apache/fpm)安装 Composer 和依赖:

FROM php:7.4-cli AS builder
WORKDIR /app
COPY composer.json composer.lock ./
RUN apt-get update && apt-get install -y unzip git && rm -rf /var/lib/apt/lists/* &&
    curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer &&
    composer install --no-dev --optimize-autoloader --no-progress

第二步:切换到精简运行阶段,使用 alpine 基础镜像并仅复制必要文件:

立即学习“PHP免费学习笔记(深入)”;

FROM php:7.4-alpine
WORKDIR /var/www/html
COPY --from=builder /app/vendor /var/www/html/vendor
COPY --from=builder /app/application /var/www/html/application
COPY --from=builder /app/extend /var/www/html/extend
COPY --from=builder /app/public /var/www/html/public
COPY --from=builder /app/think /var/www/html/think
COPY --from=builder /app/config /var/www/html/config
COPY --from=builder /app/runtime /var/www/html/runtime
COPY --from=builder /app/common.php /var/www/html/common.php
COPY --from=builder /app/index.php /var/www/html/public/index.php
EXPOSE 80
ENTRYPOINT ["php", "public/index.php"]

这一步必须严格区分路径——【runtime 目录不能直接 COPY,需在容器启动时初始化为空目录】,否则会继承 builder 阶段的缓存文件,导致权限错误或日志写入失败。

删掉所有开发期残留

方法一:在 builder 阶段末尾加清理命令,防止 vendor 中混入 .git、tests、docs 等非运行必需内容:

RUN find /app/vendor -name ".git" -type d -exec rm -rf {} + 2>/dev/null || true &&
    find /app/vendor -name "tests" -type d -exec rm -rf {} + 2>/dev/null || true &&
    find /app/vendor -name "docs" -type d -exec rm -rf {} + 2>/dev/null || true

方法二:用 .dockerignore 排除源码中无用文件,避免它们被 COPY 进 builder 阶段:

.git
node_modules
tests
docs
README.md
.env.example
composer.phar

注意:【.dockerignore 必须放在构建上下文根目录,且文件名大小写必须为小写 .dockerignore】,写成 DOCKERIGNORE 或 .Dockerignore 都不会生效。

启用 OPcache 并禁用 Xdebug

在 alpine 运行阶段的 Dockerfile 中追加 PHP 配置指令:

RUN docker-php-ext-enable opcache &&
    { echo 'opcache.enable=1';
      echo 'opcache.memory_consumption=128';
      echo 'opcache.interned_strings_buffer=8';
      echo 'opcache.max_accelerated_files=4000';
      echo 'opcache.revalidate_freq=60';
      echo 'opcache.fast_shutdown=1'; } > /usr/local/etc/php/conf.d/opcache.ini

这一步操作起来很简单,直接把配置写进 ini 文件就行。但必须确认 Xdebug 没被意外启用——alpine 镜像默认不装 Xdebug,只要没手动 RUN pecl install xdebug 就安全;若已装,必须加 RUN rm -rf /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini 彻底清除。

用 Dive 定位隐藏大文件

① 安装 Dive(Ubuntu/Debian):

sudo apt-get install dive

② 构建并立即分析镜像:

dive build -t tp51-prod .

③ 启动后按 ↑↓ 键切换图层,在右侧面板观察文件树,重点关注 public/static、public/uploads、vendor/composer/archives 这三个路径下的文件大小。如果发现某层新增了超过 5MB 的 .zip 或 .tar.gz 文件,说明 composer install 未加 --no-dev 导致下载了测试包。

④ 按 c 键进入对比模式,输入原始镜像标签(如 tp51-dev),直观查看哪些文件被成功剔除。此时左下角显示的“Image Efficiency”若低于 60%,说明仍有冗余可挖。

相关文章

精彩推荐