Docker 多阶段构建:把镜像体积砍掉八成的入门实战

举报
yd_262275629 发表于 2026/10/22 19:56:02 2026/10/22
【摘要】 为什么你的镜像越来越大?刚接触 Docker 的同学常会遇到一个尴尬:一个简单的 Web 服务,打出来的镜像动不动就超过 1GB。原因很简单——构建时需要的编译器、依赖包和各种中间文件,全都被一股脑打包进了最终镜像。而实际运行阶段需要的,往往只是一个编译好的二进制文件,或者精简的语言运行时。Docker 在 17.05 版本引入的多阶段构建(Multi-stage Build)正是为了解决这...

为什么你的镜像越来越大?


刚接触 Docker 的同学常会遇到一个尴尬:一个简单的 Web 服务,打出来的镜像动不动就超过 1GB。原因很简单——构建时需要的编译器、依赖包和各种中间文件,全都被一股脑打包进了最终镜像。而实际运行阶段需要的,往往只是一个编译好的二进制文件,或者精简的语言运行时。


Docker 在 17.05 版本引入的多阶段构建(Multi-stage Build)正是为了解决这个问题:允许在一个 Dockerfile 里写多个 FROM 指令,前面的阶段负责构建,后面的阶段只复制构建产物,最终镜像里干干净净,不留一点构建垃圾。


核心语法:一个 Dockerfile,多个 FROM


第一阶段负责构建:

FROM golang:1.22 AS builder

WORKDIR /app

COPY . .

RUN go build -o server ./cmd/server


第二阶段负责运行:

FROM alpine:3.20

WORKDIR /app

COPY --from=builder /app/server .

EXPOSE 8080

CMD ["./server"]


关键点只有两个:第一,每个 FROM 都会开启一个全新的构建阶段,可以用 AS 给阶段起别名;第二,用 COPY --from=别名 把上一个阶段的产物复制过来,其余的构建依赖和中间文件会被自动丢弃。最终镜像只包含 alpine 基础系统加一个二进制文件,体积通常只有几十 MB。


实战:Python 项目同样适用


Python 项目没有编译环节,但一样可以用多阶段构建来隔离构建依赖。构建阶段用完整镜像安装依赖:

FROM python:3.12 AS builder

WORKDIR /app

COPY requirements.txt .

RUN pip install --user --no-cache-dir -r requirements.txt


运行阶段换成 slim 精简镜像:

FROM python:3.12-slim

WORKDIR /app

COPY --from=builder /root/.local /root/.local

COPY . .

ENV PATH=/root/.local/bin:$PATH

CMD ["python", "app.py"]


总体积能从近 1GB 降到 150MB 左右,部署和拉取速度都快了一大截。


三个实用小技巧


1. 善用层缓存:把不常变化的文件(如 requirements.txt、go.mod)先 COPY 并安装依赖,源代码放到最后 COPY,这样日常改代码不会触发依赖层重建,构建飞快。

2. 阶段命名见名知意:builder、tester、runner,阶段一多可读性优势非常明显。

3. 单独调试构建阶段:docker build --target builder -t myapp:debug . 可以只构建到指定阶段,排查构建问题时非常顺手。


小结


多阶段构建几乎没有额外的学习成本,却能同时改善镜像体积、安全性和构建速度。从今天起,试着给你的 Dockerfile 加上第二个 FROM 吧。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。