首页/云/云与容器速查/多阶段构建(Multi-stage build)
容器与 Docker106 条

多阶段构建(Multi-stage build)

一个 Dockerfile 多个 FROM 阶段:编译工具链留在中间阶段,最终镜像只 COPY 运行产物。Go/Rust/前端项目常用,体积可从 GB 级降到几十 MB。

云与容器速查云更新于 2026-10-13

多阶段构建是什么

多阶段构建把一份构建文件分成多个阶段:编译工具链、依赖与中间产物留在前面的阶段,最终阶段只把运行需要的产物复制过来。好处很直接:编译环境不进产物镜像,体积更小、依赖更少、推送更快,攻击面也随之收窄,是编译型语言与前端项目的常规做法。

基本信息

原理每个阶段独立,前面的阶段默认被丢弃,产物按需复制
阶段引用复制时可按阶段名称引用,也可按出现顺序的序号引用
调试方式构建时可以只构建到指定阶段,便于验证编译结果
收益编译依赖与工具链不进产物镜像,体积与攻击面同时下降
成本构建缓存仍会占用构建机磁盘,需要定期清理
适用项目编译型语言、前端打包、需要运行多个构建步骤的项目

典型使用场景

  • 前端项目:在一个阶段安装依赖并打包,另一个阶段只放运行时与静态文件
  • 编译型语言:在构建阶段编译出可执行文件,运行阶段只带运行时库
  • 减小镜像体积:把体积从数百兆压到几十兆,缩短拉取与发布时间
  • 隔离构建依赖:避免版本库、编译器与包管理器出现在生产镜像里
  • 统一构建环境:把工具链版本固化在构建阶段,保证不同机器构建结果一致
  • 分离调试镜像:保留一个带工具的阶段,需要排查时单独构建使用

写法对照

写法含义使用注意
多个构建阶段声明每个阶段独立命名名称便于后续引用
复制阶段产物从指定阶段复制文件路径取自该阶段文件系统,不是构建机
按序号引用按阶段出现顺序引用插删阶段后序号会变化,建议用具名
指定目标阶段只构建到某个阶段用于调试与产物校验
运行阶段基础镜像选择精简运行时需确认动态库与证书齐备

前端场景示例

前端场景示例
FROM node:20-bookworm-slim AS build
WORKDIR /src
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM nginx:1.27-alpine
COPY --from=build /src/dist /usr/share/nginx/html
# 构建阶段不会进入最终镜像,工具链与依赖都留在中间层
未使用的中间阶段不会进入最终镜像,但构建缓存会占用构建机磁盘:日常配合清理命令回收空间,否则构建机往往先于业务出现磁盘告警。
复制路径的语义容易混淆:它取的是阶段内文件系统的路径,不是构建机上的目录,镜像内路径写错时会报找不到文件。
运行阶段的基础镜像要选对:过于精简的镜像可能缺少时区数据、证书或动态库,表现为程序能启动但访问外部服务失败。
调试时只构建到中间阶段:可以进到该阶段里检查产物是否完整,比反复构建完整镜像再排查效率高得多。

落地建议

  • 构建阶段与运行阶段的依赖分开维护,职责更清晰
  • 运行阶段选择带证书与时区数据的基础镜像
  • 为调试保留一个带工具的阶段,但不进入最终镜像
  • 固定构建阶段的基础镜像版本,保证构建结果可复现
  • 定期重新构建以获取基础镜像的安全更新

易错点

  • 复制阶段产物时写成构建机路径,构建直接失败
  • 在最终阶段又装了一遍构建依赖,多阶段的意义全丢
  • 运行阶段基础镜像过于精简,缺少证书或时区数据导致运行时异常
  • 按序号引用阶段,插入新阶段后引用错位,复制到错误内容
  • 从不清理构建缓存,构建机磁盘被逐步占满

数据来源与参考

  • Docker Docs:Multi-stage builds

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌