Docker 镜像从 1.2G 瘦到 180M:多阶段构建实战笔记
一个普通的 Python 服务镜像,通过多阶段构建、基础镜像替换和层合并,体积压缩到原来的六分之一,构建时间反而更短。
前段时间帮朋友看一个部署问题,发现他的镜像 1.2G,拉取一次要等好几分钟。看完 Dockerfile,瘦身空间比我想的大得多。

优化前的问题清单
- 基础镜像用了完整的发行版镜像,光系统就 900M;
- 构建工具(编译器、头文件)留在了最终镜像里;
- 每一层都单独写了一条
RUN,缓存清理没做在同一层; - 把测试代码和文档一起打进了生产镜像。
第一步:换基础镜像
把完整发行版换成 slim 版本,或者更极端的 Alpine。这一步通常能省掉一半以上体积,代价是要注意 glibc 与 musl 的差异。
# 之前
FROM ubuntu:24.04
# 之后
FROM python:3.11-slim

第二步:多阶段构建
把「编译」和「运行」拆成两个阶段,运行阶段只拷贝需要的东西。这一步是瘦身效果最明显的。
FROM python:3.11-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --prefix=/install -r requirements.txt
FROM python:3.11-slim
WORKDIR /app
COPY --from=builder /install /usr/local
COPY app ./app
CMD ["python", "-m", "app"]
第三步:层合并与清理
把安装、清理写在同一条 RUN 里,否则删掉的文件仍然存在于上一层。加上 .dockerignore 排除 .git、缓存和测试数据,效果立竿见影。
结果对比
| 指标 | 优化前 | 优化后 |
|---|---|---|
| 镜像体积 | 1.21 GB | 183 MB |
| 拉取耗时(家宽) | 3 分 40 秒 | 24 秒 |
| 构建耗时 | 4 分 10 秒 | 2 分 05 秒 |
镜像小不只是省硬盘:部署更快、攻击面更小、滚动更新时对带宽更友好。