全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-21 6 分钟 ✍️ juanwangdev

多阶段构建优化

多阶段构建是减小镜像体积的关键技术,下面介绍使用方法。

基本概念

多阶段构建在一个 Dockerfile 中使用多个 FROM 指令,每个阶段可独立产出:

dockerfile
# 第一阶段:编译环境
FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp .

# 第二阶段:运行环境
FROM alpine:3.18
WORKDIR /root
COPY --from=builder /app/myapp .
CMD ["./myapp"]

最终镜像仅包含第二阶段的内容,编译工具和源码被丢弃,显著减小体积。

Go 应用示例

单阶段构建(体积大)

dockerfile
FROM golang:1.21
WORKDIR /app
COPY . .
RUN go build -o myapp .
CMD ["./myapp"]

镜像大小:~800MB(包含 Go 编译环境)

多阶段构建(体积小)

dockerfile
# 编译阶段
FROM golang:1.21 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o myapp .

# 运行阶段
FROM alpine:3.18
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/myapp .
CMD ["./myapp"]

镜像大小:~10MB(仅包含运行时需要)

Node.js 应用示例

dockerfile
# 依赖安装阶段
FROM node:18-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

# 构建阶段
FROM node:18-alpine AS builder
WORKDIR /app
COPY . .
COPY --from=deps /app/node_modules ./node_modules
RUN npm run build

# 运行阶段
FROM node:18-alpine AS runner
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
CMD ["node", "dist/server.js"]

Java 应用示例

dockerfile
# 编译阶段
FROM maven:3.9-eclipse-temurin-17 AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn package -DskipTests

# 运行阶段
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY --from=builder /app/target/*.jar app.jar
CMD ["java", "-jar", "app.jar"]

命名阶段

dockerfile
FROM golang:1.21 AS build-env
# ...

FROM alpine:3.18
COPY --from=build-env /app/myapp .
dockerfile
# 使用索引引用
FROM golang:1.21
# ...

FROM alpine:3.18
COPY --from=0 /app/myapp .

使用命名别名提高可读性,索引引用(0, 1, 2...)更简洁但不易读。

外部镜像作为阶段

dockerfile
FROM nginx:alpine AS final
COPY --from=builder /app/dist /usr/share/nginx/html

可以从外部镜像拷贝文件,不限于当前 Dockerfile 的阶段。

要点总结

  • 多阶段构建使用多个 FROM 指令,每个阶段独立产出
  • 最终镜像仅包含最后一个阶段的内容,体积显著减小
  • 编译/构建阶段使用完整镜像,运行阶段使用精简镜像
  • 使用 AS 命名阶段提高可读性,COPY --from=阶段名 引用
  • 可从外部镜像拷贝文件,不限于当前 Dockerfile 的阶段

📝 发现内容有误?点击此处直接编辑

← 上一篇 ENTRYPOINT 与 CMD 区别
下一篇 → Compose 网络与卷
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库