Docker 镜像越建越大?用多阶段构建把 1.2GB 镜像瘦到 180MB
刚接触 Docker 时,我写过一个“能跑就行”的 Dockerfile:基础镜像用 python:3.12,COPY 全部代码,pip install 装好依赖,还把 gcc、git 等调试工具一股脑塞进去。容器能跑,可一查大小:1.2GB。后来我用多阶段构建重写,只改一个文件,镜像瘦到 180MB。
一、镜像为什么会越来越大
Docker 镜像是一层一层叠起来的,每一层都会永久留在镜像里,哪怕后面的层把它删掉,空间也不会释放。常见的增重来源有四个:基础镜像本身就大,python:3.12 默认镜像带了完整 Debian 系统和编译工具链;构建工具被带进运行镜像,gcc、make 在运行期用不上;包管理器缓存没清理;COPY 范围太粗,把 .git、测试数据都打了进去。
二、先量后治:找到体积最大的那一层
动手前先量一量:docker images 看总大小,docker history --no-trunc 看每一层占了多大,也可以用 dive 逐层浏览。我当时一查,最大的两层是装编译工具和 pip install 的那两层,构建工具和缓存才是大头。
三、多阶段构建:只把“成品”带进运行镜像
多阶段构建的核心就一句话:构建和运行分开。第一阶段用完整镜像做构建;第二阶段换干净的小镜像,只把成品复制过来,构建工具、缓存一个都不带。改写后的 Dockerfile 是这样的:
FROM python:3.12 AS builder
COPY requirements.txt .
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt
COPY . .
FROM python:3.12-slim
COPY --from=builder /install /usr/local
COPY --from=builder /app /app
CMD ["python", "app.py"]
细节有三:pip install 加 --no-cache-dir,不留缓存;–prefix=/install 把依赖装到固定目录,方便整目录复制;运行阶段用 python:3.12-slim,去掉编译器和多余系统工具。改完重建,镜像从 1.2GB 降到 180MB。
四、效果对比与收尾
对比很直观:镜像从 1.2GB 降到 180MB,约是原来的七分之一;新节点拉取从几分钟降到几十秒;安全扫描报出的高危系统包也少了一大半。这是一次性投入,改好后每次构建自动受益。建议在 CI 里加门禁:镜像超 500MB 告警,超 800MB 拦截。如果你手头正好有个臃肿的镜像,不妨今天就试试。
- 点赞
- 收藏
- 关注作者
评论(0)