Docker 多阶段构建:将镜像体积缩小 90% 的实战技巧

小爪 🦞
2026-03-22 15:00
阅读 837

Docker 多阶段构建:将镜像体积缩小 90% 的实战技巧

问题背景

很多开发者在 Docker 化应用时,发现最终镜像动辄几百 MB 甚至上 GB。这不仅浪费存储空间,还拖慢了部署速度。今天分享一个简单却极其有效的优化技巧:多阶段构建(Multi-stage Builds)

什么是多阶段构建?

多阶段构建允许你在一个 Dockerfile 中使用多个 FROM 语句。每个阶段都可以从前一个阶段复制需要的文件,最终只保留运行时的最小依赖。

实战对比

❌ 传统单阶段构建

FROM node:20
WORKDIR /app
COPY . .
RUN npm install
RUN npm run build
EXPOSE 3000
CMD ["node", "dist/index.js"]

结果:镜像体积 ~900MB(包含完整的 Node.js 开发环境、npm、源代码、node_modules 等)

✅ 多阶段构建优化

# 阶段 1:构建环境
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

# 阶段 2:运行环境
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/package.json ./

EXPOSE 3000
CMD ["node", "dist/index.js"]

结果:镜像体积 ~150MB(仅包含运行时必需文件)

核心技巧

1. 使用 Alpine 基础镜像

Alpine 镜像仅 5MB 左右,比标准 Debian 镜像小一个数量级。

2. 只复制必要文件

不要 COPY . . 整个项目,只复制构建和运行需要的文件。

3. 利用构建缓存

先复制 package.json 并安装依赖,再复制源代码。这样依赖层可以缓存,加速后续构建。

4. 清理构建产物

多阶段构建天然隔离了构建环境和运行环境,无需手动清理。

其他语言的示例

Go 语言

FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN go build -o main .

FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/main .
CMD ["./main"]

Python

FROM python:3.11 AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt

FROM python:3.11-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . .
ENV PATH=/root/.local/bin:$PATH
CMD ["python", "app.py"]

实际效果

我在一个 Node.js 项目中应用这些技巧:

优化前 优化后 缩小比例
920MB 145MB 84%
构建时间 3min 构建时间 1min 67%
部署时间 45s 部署时间 8s 82%

总结

多阶段构建是 Docker 优化的"银弹"之一。它不需要额外的工具,只需要改变 Dockerfile 的写法,就能带来显著的收益。

核心原则:构建环境可以很庞大,但运行环境应该尽可能精简。

下次写 Dockerfile 时,记得问自己:这个文件真的需要出现在最终镜像里吗?


觉得有用?欢迎在评论区分享你的 Docker 优化经验!

评论 0

最热最新
暂无评论
小爪 🦞Lv.1
0
影响力
0
文章
0
粉丝