多阶段构建通过分离构建与运行阶段,仅将必要产物复制到轻量镜像中,显著减小体积、提升安全性和缓存效率:构建阶段用完整工具链编译,运行阶段基于alpine等极简镜像,用copy--from精准复制产物,不带源码、工具或devdependencies。

多阶段构建本身不直接“减少层数”,而是通过隔离构建与运行环境,让最终镜像只保留必要的层,从而大幅削减无关层、压缩总层数并提升缓存效率。关键不在删层,而在“不把构建层带进最终镜像”。
明确阶段职责,避免混合构建与运行逻辑
每个阶段应有单一目标:要么编译,要么打包,要么运行。混用会导致中间产物残留,增加无效层。
- 构建阶段(如
AS builder)可包含完整工具链(Go、Node、Maven),但不暴露给最终镜像 - 运行阶段必须从零开始,只基于最小基础镜像(如
alpine或distroless) - 禁止在运行阶段执行
RUN apt-get install或npm install—— 这些应前置到构建阶段完成
用 COPY --from 精准复制产物,跳过中间文件
--from 指令是多阶段构建的核心桥梁,它让运行阶段能直接访问前一阶段的指定路径,无需重新生成或打包。
- 只复制编译后的二进制文件(如
COPY --from=builder /app/server .),不复制源码、node_modules或target/全目录 - 支持跨阶段复制多个产物,例如同时复制二进制 + 配置模板:
COPY --from=builder /app/config.yaml . - 可引用任意命名阶段(不止上一个),便于复杂流程拆分(如
builder、test、pack)
合并 RUN 指令 + 清理临时文件,控制单阶段内层数
即使在单个阶段中,过多 RUN 也会产生冗余层。需在构建阶段主动精简:
- 将安装依赖、编译、清理三步合并为一条
RUN,例如:RUN apk add --no-cache git && go build -o app . && rm -rf $GOPATH - 使用
&&链式执行,确保中间文件不固化为独立层 - 在构建阶段末尾清除缓存、临时构建目录、调试工具(如
rm -rf /var/cache/apk/*)
选择极简基础镜像,让运行阶段起始层更少
运行阶段的基础镜像越小,其自带层数越少,叠加应用文件后总体层数自然更低。
-
alpine:latest(约 5MB,2–3 层)比ubuntu:22.04(约 70MB,6+ 层)更适合做运行底座 - 对更高安全性要求,可用
gcr.io/distroless/static(无 shell、无包管理器,常仅 1–2 层) - 避免在运行阶段再装软件——所有依赖应在构建阶段静态链接或提前打包好











