多阶段构建
多阶段构建是优化镜像大小的强大技术,可以在一个 Dockerfile 中使用多个 FROM 指令。
为什么需要多阶段构建?
问题:单阶段构建体积大
FROM node:18WORKDIR /appCOPY package*.json ./RUN npm installCOPY . .RUN npm run buildCMD ["node", "dist/server.js"]问题:最终镜像包含了构建工具和源代码,体积很大(~1GB)。
解决方案:多阶段构建
# 构建阶段FROM node:18 AS builderWORKDIR /appCOPY package*.json ./RUN npm installCOPY . .RUN npm run build
# 运行阶段FROM node:18-alpineWORKDIR /appCOPY --from=builder /app/dist ./distCOPY --from=builder /app/node_modules ./node_modulesCMD ["node", "dist/server.js"]最终镜像只包含运行时需要的文件,体积大幅减小(~200MB)。
Go 应用示例
# 编译阶段FROM golang:1.21-alpine AS builderWORKDIR /buildCOPY go.mod go.sum ./RUN go mod downloadCOPY . .RUN CGO_ENABLED=0 GOOS=linux go build -o app .
# 运行阶段FROM alpine:latestRUN apk --no-cache add ca-certificatesWORKDIR /root/COPY --from=builder /build/app .EXPOSE 8080CMD ["./app"]镜像大小对比:
- 单阶段:~800MB
- 多阶段:~10MB
Python 应用示例
# 构建阶段FROM python:3.11 AS builderWORKDIR /appCOPY requirements.txt .RUN pip install --user -r requirements.txt
# 运行阶段FROM python:3.11-slimWORKDIR /appCOPY --from=builder /root/.local /root/.localCOPY . .ENV PATH=/root/.local/bin:$PATHCMD ["python", "app.py"]前端应用示例
# 构建阶段FROM node:18 AS builderWORKDIR /appCOPY package*.json ./RUN npm ciCOPY . .RUN npm run build
# 运行阶段(使用 Nginx 提供静态文件)FROM nginx:alpineCOPY --from=builder /app/dist /usr/share/nginx/htmlEXPOSE 80CMD ["nginx", "-g", "daemon off;"]高级技巧
命名构建阶段
FROM node:18 AS dependenciesWORKDIR /appCOPY package*.json ./RUN npm ci
FROM node:18 AS builderWORKDIR /appCOPY --from=dependencies /app/node_modules ./node_modulesCOPY . .RUN npm run build
FROM node:18-alpine AS runnerWORKDIR /appCOPY --from=builder /app/dist ./distCMD ["node", "dist/server.js"]使用外部镜像
# 从其他镜像复制文件FROM nginx:alpineCOPY --from=myregistry/static-files:latest /app /usr/share/nginx/html构建特定阶段
# 只构建到 builder 阶段docker build --target builder -t myapp:builder .
# 构建完整镜像docker build -t myapp:latest .最佳实践
- ✅ 构建阶段使用完整镜像
- ✅ 运行阶段使用精简镜像(alpine/slim)
- ✅ 只复制必要的文件
- ✅ 为每个阶段命名
- ✅ 利用构建缓存
镜像大小对比
| 应用类型 | 单阶段 | 多阶段 | 减少 |
|---|---|---|---|
| Node.js | ~1GB | ~200MB | 80% |
| Go | ~800MB | ~10MB | 99% |
| Python | ~1GB | ~150MB | 85% |
| React | ~1.5GB | ~25MB | 98% |
下一步
- 镜像优化 - 更多优化技巧
- Dockerfile 基础 - 基础知识回顾
- 生产环境部署 - 部署最佳实践