Docker 多阶段构建

多阶段构建的核心思想:builder 阶段编译,runtime 阶段只包含产物。镜像体积从 1GB+ 降到 30MB。分层缓存优化构建速度。

#type / concept #status / growing #tech / ops #resource / docker

[!info] related notes

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 等不需要的文件。

创建于 2026/6/25 更新于 2026/6/25