news 2026/4/26 16:01:42

Docker多阶段构建(Multi-stage Build)介绍(distroless镜像 / slim基础镜像、slim镜像)(FROM指令的本质)胖镜像瘦镜像、COPY . .、FROM命令

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Docker多阶段构建(Multi-stage Build)介绍(distroless镜像 / slim基础镜像、slim镜像)(FROM指令的本质)胖镜像瘦镜像、COPY . .、FROM命令

文章目录

  • 🚀 多阶段构建与精简基础镜像(distroless / slim)实践指南
    • 📦 一、为什么需要优化镜像?
      • ❌ 问题
    • 🧱 二、什么是多阶段构建(Multi-stage Build)?
      • ✅ 核心思想
      • 🧩 示例(Go 项目)
      • 🎯 优势
    • 📌 三、distroless 镜像详解
      • 📌 什么是 distroless?
      • 🚫 distroless 不包含:
      • ✅ distroless 包含:
      • 📦 常见 distroless 镜像
      • 🎯 优势
      • ⚠️ 缺点
    • 📌 四、slim 镜像详解
      • 📌 什么是 slim?
      • ✅ 特点
      • 🎯 优势
      • ⚠️ 缺点
    • ⚖️ 五、distroless vs slim 对比
    • 🧪 六、推荐组合:多阶段 + distroless
      • 🎯 思路总结
    • 🔐 七、安全最佳实践
      • ✅ 1. 使用最小权限
      • ✅ 2. 明确入口
      • ✅ 3. 扫描漏洞
      • ✅ 4. 固定版本
    • 🧯 八、调试技巧(distroless)
      • 方法 1:临时切换 slim
      • 方法 2:使用 debug 版本
      • 方法 3:Sidecar 调试
    • 🧩 九、适用场景总结
    • 🏁 十、总结
  • 补充:FROM指令的本质
    • 多阶段构建的工作机制
      • 阶段1:构建阶段
      • 阶段2:运行阶段
    • 关键点理解
      • 1. **每个FROM都是独立的起点**
      • 2. **为什么需要这样?**
      • 3. **COPY --from的作用**
    • 类比理解
    • 单阶段构建的对比
    • 总结

🚀 多阶段构建与精简基础镜像(distroless / slim)实践指南

在容器化逐渐成为基础设施标准的今天,如何构建更小、更安全、更高效的镜像,已经成为工程团队的重要课题。

本文将围绕三个核心点展开:

  • 什么是多阶段构建(Multi-stage Build)
  • 什么是 distroless / slim 镜像
  • 如何在实际项目中结合使用

📦 一、为什么需要优化镜像?

在默认情况下,我们常见的 Dockerfile 可能是这样的:

FROM golang:1.22 WORKDIR /app COPY . . RUN go build -o app CMD ["./app"]

这种写法存在几个明显问题:

❌ 问题

  • 镜像体积大(包含完整编译环境)
  • 包含无关工具(gcc、git 等)
  • 攻击面大(潜在漏洞更多)
  • 启动速度慢(镜像大)

👉 这正是多阶段构建和精简镜像要解决的问题。


🧱 二、什么是多阶段构建(Multi-stage Build)?

多阶段构建是 Docker 提供的一种构建机制:

👉 允许在一个 Dockerfile 中使用多个FROM,每个阶段只做一件事。


✅ 核心思想

构建环境 ≠ 运行环境


🧩 示例(Go 项目)

# 第一阶段:构建 FROM golang:1.22 AS builder WORKDIR /app COPY . . RUN CGO_ENABLED=0 GOOS=linux go build -o app # 第二阶段:运行 FROM gcr.io/distroless/base WORKDIR /app COPY --from=builder /app/app . CMD ["./app"]

注:COPY . .是 Dockerfile 中的复制指令,具体含义如下:

  • 第一个.:表示源路径,指的是构建上下文的根目录(即包含 Dockerfile 的目录,宿主机)
  • 第二个.:表示目标路径,指的是当前工作目录(由前面的WORKDIR /app指定,容器内)

作用:将本地项目目录中的所有文件和子目录(除了.dockerignore中排除的文件)复制到容器的/app目录中。


🎯 优势

优势说明
镜像更小只包含最终二进制
更安全不包含编译工具
更清晰构建与运行分离
更快部署镜像传输更快

📌 三、distroless 镜像详解

📌 什么是 distroless?

distroless = 无发行版(no distro)

由 Google 推出的一类镜像:

👉只包含运行应用所需的最小依赖


🚫 distroless 不包含:

  • shell(没有 bash / sh)
  • 包管理器(apt / yum)
  • 调试工具(curl / ps)

✅ distroless 包含:

  • 应用运行时依赖(glibc 等)
  • 证书(CA certs)
  • 最小系统库

📦 常见 distroless 镜像

镜像用途
distroless/base通用基础
distroless/static静态编译程序
distroless/javaJava 应用
distroless/nodejsNode.js 应用

🎯 优势

  • 🔐 更安全(极小攻击面)
  • ⚡ 更小(几十 MB 甚至更小)
  • 🚀 更快启动

⚠️ 缺点

  • 无法进入容器调试(没有 shell)
  • 排查问题困难
  • 学习成本较高

📌 四、slim 镜像详解

相比 distroless,“slim” 是一种折中方案。


📌 什么是 slim?

例如:

  • python:3.12-slim
  • node:20-slim

👉 是官方镜像的“精简版”


✅ 特点

  • 保留基础操作系统(Debian slim)
  • 去掉文档、缓存、开发工具
  • 仍然可以apt install

🎯 优势

  • 比完整镜像小很多
  • 仍然可调试
  • 使用门槛低

⚠️ 缺点

  • 仍然包含 OS → 攻击面较大
  • 体积比 distroless 大

⚖️ 五、distroless vs slim 对比

维度distrolessslim
体积⭐ 最小⭐⭐ 较小
安全性⭐⭐⭐ 极高⭐⭐ 中等
可调试性❌ 几乎没有✅ 支持
使用难度较高较低
适用场景生产环境开发/测试

🧪 六、推荐组合:多阶段 + distroless

👉 最佳实践:

# 构建阶段 FROM node:20 AS builder WORKDIR /app COPY package*.json ./ RUN npm install COPY . . RUN npm run build # 运行阶段 FROM gcr.io/distroless/nodejs20 WORKDIR /app COPY --from=builder /app . CMD ["server.js"]

🎯 思路总结

  • 构建阶段:用“胖镜像”(带工具)
  • 运行阶段:用“瘦镜像”(无工具)

🔐 七、安全最佳实践

✅ 1. 使用最小权限

USER nonroot

✅ 2. 明确入口

CMD ["./app"]

避免 shell 形式:

CMD ./app # ❌

✅ 3. 扫描漏洞

推荐工具:

  • Trivy
  • Grype

✅ 4. 固定版本

FROM node:20.11.1-slim

避免:

FROM node:latest # ❌

🧯 八、调试技巧(distroless)

distroless 最大痛点:无法 debug

👉 解决方案:

方法 1:临时切换 slim

FROM node:20-slim

方法 2:使用 debug 版本

gcr.io/distroless/base:debug

方法 3:Sidecar 调试

在 Kubernetes 中使用 sidecar 容器。


🧩 九、适用场景总结

场景推荐
CI 构建多阶段
生产环境distroless
本地开发slim
需要调试slim

🏁 十、总结

多阶段构建 + 精简镜像,是现代容器化的标配:

✅ 更小
✅ 更安全
✅ 更快

建议逐步演进:

  1. 先引入多阶段构建
  2. 再切换到slim
  3. 最终在生产使用distroless

补充:FROM指令的本质

FROM确实是以某个镜像为基础进行构建,但在多阶段构建中,每个FROM创建一个独立的构建阶段,它们之间是相互隔离的。

多阶段构建的工作机制

阶段1:构建阶段

FROM golang:1.22 AS builder ## ← 第1个FROM WORKDIR /app COPY . . RUN CGO_ENABLED=0 GOOS=linux go build -o app
  • 基于golang:1.22镜像创建一个临时容器
  • 在这个容器中编译Go代码
  • 生成的app二进制文件存在于这个阶段的文件系统中

阶段2:运行阶段

FROM gcr.io/distroless/base ## ← 第2个FROM WORKDIR /app COPY --from=builder /app/app . ## ← 从阶段1复制文件 CMD ["./app"]
  • 重新开始,基于distroless/base创建一个全新的容器
  • 这个阶段不知道阶段1的存在(除了通过COPY --from显式复制的文件)
  • 只包含运行时需要的最小文件

关键点理解

1.每个FROM都是独立的起点

阶段1: golang:1.22 → 编译环境(~1GB) ↓ 编译出app二进制文件 ↓ 阶段2: distroless/base → 运行环境(~10MB) ↑ COPY --from=builder 复制二进制文件

2.为什么需要这样?

  • 构建阶段需要完整的Go工具链(编译器、标准库等)
  • 运行阶段只需要编译好的二进制文件
  • 如果只用一个阶段,最终镜像会包含整个Go环境(浪费空间且不安全)

3.COPY --from的作用

COPY --from=builder /app/app . ## ↑ ↑ ↑ ## 从阶段1 阶段1的路径 复制到当前阶段

类比理解

可以把多阶段构建想象成搬家

  1. 阶段1(原房子):你在一个大房子里(golang:1.22)整理所有物品,打包好需要的东西
  2. 阶段2(新房子):你搬到一个空房子(distroless/base),只把打包好的必需品搬进来
  3. 结果:新房子很干净,没有原房子里的杂物

单阶段构建的对比

如果只用单阶段:

FROM golang:1.22 WORKDIR /app COPY . . RUN go build -o app CMD ["./app"]

问题:最终镜像包含整个Go环境(~1GB),而实际只需要一个几MB的二进制文件!

总结

  • 每个FROM创建一个独立的构建上下文
  • 阶段之间通过COPY --from=<阶段名>传递文件
  • 最终镜像只包含最后一个阶段的内容
  • 这就是为什么可以"前面以这个为基,后面又以另一个为基"

多阶段构建的本质是:用不同的基础镜像完成不同的任务,最终只保留需要的结果

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/26 16:00:47

G-Helper终极指南:华硕笔记本性能管理一键优化方案

G-Helper终极指南&#xff1a;华硕笔记本性能管理一键优化方案 【免费下载链接】g-helper Lightweight, open-source control tool for ASUS laptops and ROG Ally. Manage performance modes, fans, GPU, battery, and RGB lighting across Zephyrus, Flow, TUF, Strix, Scar,…

作者头像 李华
网站建设 2026/4/26 15:58:46

ILSpy BAML反编译器:解决WPF二进制界面逆向工程的技术挑战

ILSpy BAML反编译器&#xff1a;解决WPF二进制界面逆向工程的技术挑战 【免费下载链接】ILSpy .NET Decompiler with support for PDB generation, ReadyToRun, Metadata (&more) - cross-platform! 项目地址: https://gitcode.com/gh_mirrors/il/ILSpy 面对WPF应用…

作者头像 李华
网站建设 2026/4/26 15:55:01

基于OpenAI Realtime API构建实时语音交互AI智能体实战指南

1. 项目概述&#xff1a;一个能与你实时对话的AI伙伴 如果你看过电影《Her》&#xff0c;一定对那个善解人意、声音温柔的AI操作系统“萨曼莎”印象深刻。现在&#xff0c;借助OpenAI的Realtime API&#xff0c;我们也能亲手打造一个属于自己的“萨曼莎”了。这个名为Samantha…

作者头像 李华
网站建设 2026/4/26 15:53:44

PPTX2HTML终极指南:3分钟实现PPTX到HTML的完美转换

PPTX2HTML终极指南&#xff1a;3分钟实现PPTX到HTML的完美转换 【免费下载链接】PPTX2HTML Convert pptx file to HTML by using pure javascript 项目地址: https://gitcode.com/gh_mirrors/pp/PPTX2HTML PPTX2HTML是一款革命性的前端转换工具&#xff0c;让您的演示文…

作者头像 李华
网站建设 2026/4/26 15:53:43

105个BitTorrent Tracker配置指南:彻底解决BT下载慢的终极方案

105个BitTorrent Tracker配置指南&#xff1a;彻底解决BT下载慢的终极方案 【免费下载链接】trackerslist Updated list of public BitTorrent trackers 项目地址: https://gitcode.com/GitHub_Trending/tr/trackerslist 还在为BT下载速度慢而烦恼吗&#xff1f;下载热门…

作者头像 李华
网站建设 2026/4/26 15:43:49

技术解析:跨平台CS2游戏增强框架如何实现零依赖高性能架构

技术解析&#xff1a;跨平台CS2游戏增强框架如何实现零依赖高性能架构 【免费下载链接】Osiris Cross-platform game hack for Counter-Strike 2 with Panorama-based GUI. 项目地址: https://gitcode.com/gh_mirrors/os/Osiris 在竞技游戏环境中&#xff0c;信息获取的…

作者头像 李华