docker镜像瘦身关键在于构建时清理而非事后处理:优先用多阶段构建分离编译与运行环境;单阶段则需链式run指令合并安装、构建与清理;显式删除源码和中间产物,并用.dockerignore过滤无关文件。

在 Docker 构建过程中,临时文件、缓存包、开发依赖等残留物会显著增大镜像体积,甚至引入安全风险。关键不是“构建完再清理”,而是把清理逻辑直接写进 Dockerfile,让每一步都只保留真正需要的内容。
利用多阶段构建剥离构建依赖
这是最推荐的方式:把编译和运行环境完全分离,只把最终产物复制到精简的运行镜像中。
- 第一阶段用完整工具链(如
golang:1.22或node:20)构建应用,生成二进制或静态资源 - 第二阶段基于极小基础镜像(如
alpine:latest或debian:slim),仅 COPY 编译结果,不带任何构建工具和源码 - 这样天然规避了
apt-get clean、npm cache clean等手动清理的遗漏风险
单阶段中使用 && 链式命令及时清理
若必须单阶段构建(如某些 C/C++ 项目或遗留系统),务必把安装、构建、清理写在同一 RUN 指令中,避免分层残留。
- 错误写法:
RUN apt-get update && apt-get install -y build-essentialRUN make allRUN apt-get clean && rm -rf /var/lib/apt/lists/*—— 中间层仍含未清理的包缓存 - 正确写法:
RUN apt-get update && apt-get install -y build-essential && make all && apt-get clean && rm -rf /var/lib/apt/lists/* - 对 Node.js 项目:
RUN npm ci --only=production && npm cache clean --force
删除源码与构建中间产物
很多项目 COPY 源码后编译,但忘了删掉 /src 或 /build 目录,导致镜像包含大量非运行所需文件。
- 在最终 RUN 指令末尾显式清理:
&& rm -rf /app/src /app/build /app/node_modules/.cache - 用
.dockerignore提前过滤无需 COPY 的文件(如node_modules/、.git/、tests/) - 对 Go 项目,可直接
COPY --from=builder /workspace/app /usr/local/bin/app,不 COPY 源码目录
验证清理效果
构建完成后别只看是否成功,要确认镜像是否真的“瘦”了。
- 用
docker history your-image:tag查看各层大小,重点关注大体积的 RUN 层 - 用
docker run --rm -it your-image:tag sh -c "du -sh /* 2>/dev/null | sort -hr"进入容器检查实际占用 - 对比清理前后镜像 size:
docker images your-image,目标是减少 30%~70% 不等(视项目而定)











