Skip to content
返回部署

Docker 多阶段构建

多阶段 Dockerfile 分离构建和运行时,生成小生产镜像。

容器进阶

为什么

多阶段构建一 Dockerfile 多 FROM — 构建阶段有所有开发依赖,最终阶段仅复制构建产物。镜像减小 10-100 倍。

Docker is used by 59% of professional developers per the Stack Overflow 2024 survey,Kubernetes 在生产中运行 60% 的容器化工作负载(CNCF 2024 调查)。容器编排通过声明式滚动发布将部署相关事故减少 35%。

何时使用

所有生产镜像用多阶段 — 更小、更安全、更快拉取。 简单静态站点跳过容器 — CDN + 静态导出更便宜更快。10 人以下团队避免 Kubernetes;运维开销不合理。

如何做

1. 构建阶段 — FROM node:20 AS build,全依赖 2. 构建 — RUN npm ci && npm run build 3. 运行时阶段 — FROM node:20-alpine,精简 4. 复制 — COPY --from=build /app/dist ./dist 5. 依赖 — COPY --from=build /app/node_modules ./ 6. CMD — 运行构建应用 7. 验证 — docker images,比较大小

示例

# Dockerfile — 多阶段 FROM node:20 AS build WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build FROM node:20-alpine WORKDIR /app COPY package*.json ./ RUN npm ci --omit=dev COPY --from=build /app/dist ./dist EXPOSE 3000 CMD ["node", "dist/server.js"] # 构建并检查大小 docker build -t myapp . docker images myapp # ~150MB vs ~1GB 单阶段

常见问题

  • ⚠复制错阶段 — COPY --from=stage-name,确保名匹配 AS 子句
  • ⚠最终含开发依赖 — 最终阶段 RUN npm ci --omit=dev,非全装
  • ⚠环境间配置漂移 — 使用基础设施即代码(Terraform/Pulumi)保持 dev/staging/prod 一致

最佳实践

  • ✓最终阶段用 alpine 或 distroless — 最小基础,最少漏洞
  • ✓仅复制所需文件 — 最终不 COPY . .,复制特定 dist/ 或 build/
  • ✓设置健康检查和优雅关闭 — 处理 SIGTERM 以在退出前排空进行中的请求

常见问题解答