一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

Docker 镜像构建多阶段如何实现

时间:2026-09-04 09:52:49 编辑:袖梨 来源:一聚教程网

多阶段构建通过FROM AS定义多个阶段,仅复制产物到极简运行镜像中。第一阶段(如builder)用完整工具链编译,第二阶段用alpine/distroless等精简镜像,通过COPY --from=阶段名提取必要文件,并创建非root用户提升安全。

多阶段构建通过一个 Dockerfile 内定义多个独立构建阶段,只把最终需要的文件复制到运行镜像中,从而剥离编译器、源码、开发依赖等非运行时内容。

用 FROM AS 定义不同阶段

每个 FROM 指令开启一个新阶段,用 AS 给它起个名字,方便后续引用:

  1. 第一阶段通常叫 builder,选用带完整工具链的镜像(如 golang:1.21node:18maven:3.8
  2. 在该阶段完成代码复制、依赖安装、编译或构建(如 go buildnpm run buildmvn package
  3. 第二阶段起用极简镜像(如 alpine:3.18distroless:nonroot),不装任何构建工具

用 COPY --from 复制产物

运行阶段不能访问前一阶段的文件系统,必须显式用 COPY --from=阶段名 拿出需要的内容:

  1. COPY --from=builder /app/dist /usr/share/nginx/html(前端静态资源)
  2. COPY --from=builder /app/myapp /usr/local/bin/(Go 编译好的二进制)
  3. 支持跨阶段复制任意路径,甚至可写 --from=0 引用第一个阶段
  4. 注意:目标路径需提前创建(如用 WORKDIRRUN mkdir -p

精简基础镜像与权限控制

最终镜像体积和安全性取决于运行阶段的选择:

  1. 优先选 alpine(5MB)、debian:slim(50MB)或 distroless(20MB);完全静态二进制可用 scratch(0MB)
  2. 避免 root 运行:添加普通用户(useradd -u 1001 -m appuser),再用 USER appuser 切换
  3. 敏感文件(如 .git、.env、测试代码)默认不会进入最终镜像——只要不复制,就不存在

验证是否真正精简

构建完成后别急着推送,先检查最终镜像里有什么:

  1. docker run --rm -it your-image sh —— 如果进不去,说明用了 distrolessscratch,这是正常现象
  2. docker run --rm -it your-image ls -la /app —— 确认只有二进制或 dist 目录,没有 src/node_modules/package.json
  3. docker history your-image —— 查看各层大小,确认构建工具层未被保留

热门栏目