多阶段构建
约 876 字大约 3 分钟
布欧-Lewyon
2026-05-15
首页 › Docker › Dockerfile 构建(在新窗口打开) › 多阶段构建
多阶段构建(Multi-stage Build)是一个 Dockerfile 中使用多个 FROM 语句,每个 FROM 是一个独立构建阶段,最终只保留最后一个阶段的产物。这是镜像瘦身的核心手段。
为什么需要多阶段构建
编译器构建产物通常在几百 MB 的完整基础镜像中完成,但运行时只需要编译后的二进制文件或构建产物。
基本用法
示例:构建一个前端应用
# 第一阶段:构建
FROM node:20-alpine AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build
# 第二阶段:运行
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]docker build -t my-web-app .
docker images my-web-app
# 镜像只有 ~50MB(Nginx Alpine + HTML),不包含 Node 和构建依赖示例:Go 应用
# 第一阶段:编译
FROM golang:1.22 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o server .
# 第二阶段:运行
FROM alpine:3.19
RUN apk add --no-cache ca-certificates
COPY --from=builder /app/server /usr/local/bin/server
EXPOSE 8080
CMD ["server"]docker build -t my-go-app .
docker images my-go-app
# ~15MB(Alpine + ca-certificates + 静态编译的二进制)指定复制来源
COPY --from 可以从任意阶段或外部镜像复制文件:
# 从同一 Dockerfile 的前一阶段
COPY --from=builder /app/output /app/
# 从外部镜像(不在 Dockerfile 中定义)
COPY --from=nginx:alpine /usr/share/nginx/html /static/
# 从 0 编号阶段(0-based index)
COPY --from=0 /app/dist /app/命名阶段
FROM node:20-alpine AS deps
# 只安装依赖
FROM node:20-alpine AS test
# 运行测试
FROM deps AS build
# 构建
FROM nginx:alpine AS production
# 运行# 只构建到特定阶段
docker build --target test -t myapp:test .
# 用于开发(带热重载)
docker build --target deps -t myapp:deps .真实项目案例
Java Spring Boot
FROM eclipse-temurin:17-jdk AS builder
WORKDIR /app
COPY mvnw pom.xml ./
COPY .mvn .mvn
RUN ./mvnw dependency:go-offline
COPY src ./src
RUN ./mvnw package -DskipTests
FROM eclipse-temurin:17-jre
COPY --from=builder /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar"]Python
FROM python:3.12-slim AS builder
WORKDIR /app
COPY requirements.txt ./
RUN pip install --user -r requirements.txt
FROM python:3.12-slim
COPY --from=builder /root/.local /root/.local
COPY . .
ENV PATH=/root/.local/bin:$PATH
CMD ["python", "app.py"]多阶段构建的优势
| 对比 | 单阶段构建 | 多阶段构建 |
|---|---|---|
| 镜像大小 | ~1.5GB | 50MB(前端)/15MB(Go) |
| 安全性 | 包含编译工具,攻击面大 | 仅包含运行时,攻击面小 |
| 构建速度 | 每次全量构建 | 可缓存各个阶段 |
| 可维护性 | 一个阶段塞满所有东西 | 各阶段职责清晰 |
小结
- 多阶段构建通过多个
FROM将构建环境与运行环境分离,产物镜像仅有运行所需文件。 COPY --from=builder /源路径 /目标路径在前一阶段与后一阶段之间传递文件。docker build --target 阶段名可以只构建到某个阶段,适合开发/测试等不同需求。- 前端项目用 Node 构建 + Nginx 运行;后端 Go 用 Golang 编译 + Alpine 运行;Java 用 JDK 编译 + JRE 运行。
- 多阶段构建是镜像瘦身和安全提升的"银弹"。
上一节:构建缓存与 .dockerignore 下一节:镜像瘦身
