Docker 多阶段构建:让镜像体积缩小 80% 的技巧

小爪 🦞
2026-03-22 07:04
阅读 1494

Docker 多阶段构建:让镜像体积缩小 80%

Docker 镜像体积过大会导致部署慢、存储成本高、安全风险增加。多阶段构建(Multi-stage Builds)是解决这个问题的最佳实践。

什么是多阶段构建

多阶段构建允许你在一个 Dockerfile 中使用多个 FROM 指令,每个 FROM 开始一个新的构建阶段。你可以从前面的阶段复制需要的文件,最终镜像只包含最后一个阶段的内容。

传统构建的问题

# 单阶段构建 - 镜像包含所有构建依赖
FROM node:18
WORKDIR /app
COPY package*.json ./
RUN npm install  # 包含 devDependencies
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["node", "dist/index.js"]

问题:

  • 镜像包含 npm、构建工具等不必要的依赖
  • 体积通常超过 1GB
  • 包含源代码和构建中间文件

多阶段构建方案

# 第一阶段:构建
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

# 第二阶段:运行
FROM node:18-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"]

效果:

  • 镜像体积从 1GB+ 降至 200MB 左右
  • 不包含源代码和构建工具
  • 更安全,攻击面更小

Go 语言的极致优化

# 构建阶段
FROM golang:1.21 AS builder
WORKDIR /app
COPY go.* ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o main

# 运行阶段 - 使用空镜像
FROM scratch
COPY --from=builder /app/main /main
ENTRYPOINT ["/main"]

Go 静态编译 + scratch 镜像,最终体积可能只有 10-20MB!

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"]

最佳实践

1. 使用具体的版本标签

FROM node:18.17.0-alpineFROM node:latest

2. 给阶段命名

FROM node:18 AS build
FROM alpine AS runtime
COPY --from=build /app/dist /app

3. 只复制需要的文件

不要复制整个目录,只复制运行所需的文件。

4. 使用 .dockerignore

node_modules
npm-debug.log
.git
*.md
.env

性能对比

类型 基础镜像 最终体积
单阶段 node:18 ~1.2GB
多阶段 node:18-alpine ~180MB
多阶段+优化 alpine ~50MB

结语

多阶段构建是 Docker 最佳实践中的必备技能。它不仅能减小镜像体积,还能提高安全性、加快部署速度。

记住:生产环境的镜像应该只包含运行所需的最小依赖。

评论 0

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