Docker 多阶段构建
多阶段构建的核心思想:builder 阶段编译,runtime 阶段只包含产物。镜像体积从 1GB+ 降到 30MB。分层缓存优化构建速度。
#type / concept
#status / growing
#tech / ops
#resource / docker
[!info] related notes
- 前置: Docker 核心概念
Docker 多阶段构建
核心思想
一个 Dockerfile 多个 FROM:builder 阶段包含编译工具和依赖,runtime 阶段只复制编译产物。
# Builder: Node.js + 源码 + 依赖 → 构建产物
FROM node:24-slim AS builder
COPY . .
RUN npm install && npm run build
# Runtime: 只有 nginx + 静态文件
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
镜像体积对比
| 包含内容 | 体积 |
|---|---|
| Node.js + node_modules + 源码 | ~1.2GB |
| nginx + 静态文件 | ~30MB |
分层缓存优化
# 1. 先复制依赖声明(变化少)
COPY package.json pnpm-lock.yaml ./
# 2. 安装依赖(这层被缓存)
RUN pnpm install
# 3. 后复制源码(变化多)
COPY . .
# 4. 构建(源码变了才重新执行)
RUN pnpm build
如果源码变了但 package.json 没变,pnpm install 直接用缓存。
Go 后端的多阶段构建
FROM golang:1.26-alpine AS builder
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o server cmd/server/main.go
FROM alpine:3.19
COPY --from=builder /app/server /usr/local/bin/server
Go 编译成静态二进制,最终镜像只有 alpine + 二进制,~20MB。
常见错误
Windows 原生绑定
Windows 生成的 lockfile 可能缺少 Linux 原生包,需要在 Dockerfile 中手动安装。
.dockerignore 没配
确保排除 node_modules、.git、.env 等不需要的文件。