Docker 分階段構建
Docker 分階段構建(Multi-stage Build)是一種高效的鏡像構建技術,允許在一個 Dockerfile 中使用多個構建階段,每個階段可以使用不同的基礎鏡像,最終只保留需要的文件,從而顯著減小鏡像體積。以下是分階段構建的核心概念和示例:
為什么使用分階段構建?
- 減小鏡像體積:最終鏡像只包含運行時所需的文件,不包含構建工具和臨時文件。
- 簡化 Dockerfile:無需手動清理中間文件,每個階段專注于特定任務。
- 提高安全性:生產環境鏡像不包含不必要的構建依賴,降低安全風險。
基本語法
使用?FROM <image> AS <stage-name>
?定義多個構建階段:
# 第一階段:構建應用(使用較大的基礎鏡像)
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build# 第二階段:運行應用(使用輕量級基礎鏡像)
FROM node:18-slim
WORKDIR /app
COPY --from=builder /app/package*.json ./
COPY --from=builder /app/dist ./dist # 只復制構建結果
RUN npm install --production # 只安裝生產依賴
CMD ["node", "dist/main.js"]
關鍵點說明
- 階段命名:使用?
AS <stage-name>
?為每個階段命名,便于后續引用。 - 文件復制:使用?
COPY --from=<stage-name>
?從之前的階段復制文件。 - 基礎鏡像選擇:構建階段可使用完整的 SDK 鏡像,運行階段使用輕量級的運行時鏡像(如?
alpine
?或?slim
)。
常見場景示例
1. Go 應用分階段構建
# 構建階段
FROM golang:1.20 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp# 運行階段
FROM alpine:3.18
WORKDIR /app
COPY --from=builder /app/myapp .
CMD ["./myapp"]
2. Java Spring Boot 應用分階段構建
# 構建階段
FROM maven:3.8.6-openjdk-11 AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn package -DskipTests# 運行階段
FROM openjdk:11-jre-slim
WORKDIR /app
COPY --from=builder /app/target/myapp.jar .
CMD ["java", "-jar", "myapp.jar"]
高級技巧
- 多階段復用:一個階段可以從多個之前的階段復制文件。
- 條件構建:使用?
--target
?參數指定構建到特定階段(用于調試):docker build --target builder -t myapp:builder .
- 緩存優化:合理安排?
COPY
?指令順序,利用 Docker 構建緩存。
注意事項
- 每個?
FROM
?語句都會創建一個新階段,之前階段的環境不會延續。 - 最終鏡像體積只包含最后一個階段的內容。
- 分階段構建不會影響構建速度,但能大幅減小鏡像體積。
通過分階段構建,你可以創建更高效、更安全的 Docker 鏡像,同時保持開發流程的簡潔性。