FROM scratch: docker 构建方式分析

bash 复制代码
FROM ubuntu:24.04 AS ubuntu

RUN rm -rf /etc/localtime
RUN rm -f /usr/lib/apt/methods/mirror
RUN usermod -s /usr/sbin/nologin sync
RUN usermod -s /usr/sbin/nologin ubuntu
RUN apt remove -y --allow-remove-essential --auto-remove login

FROM scratch

LABEL "org.opencontainers.image.ref.name"="ubuntu"
LABEL "org.opencontainers.image.version"="24.04"

ENV PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
CMD ["/bin/bash"]

COPY --from=ubuntu / /

这个 Dockerfile 中两个FROM指令的关系是多阶段构建中的 "基础阶段" 与 "最终阶段",通过 "阶段复用" 实现镜像精简和定制化,具体关系和作用如下:

1. 两个 FROM的角色与关系

阶段 FROM指令 角色定位 与另一阶段的关系
第一阶段 FROM ubuntu:24.04 AS ubuntu 基础构建阶段 (命名为ubuntu 基于官方ubuntu:24.04镜像进行预处理,为最终阶段提供 "净化后的基础文件系统"
第二阶段 FROM scratch 最终镜像阶段 以空镜像(scratch)为起点,仅复制第一阶段处理后的文件系统,构建极小化最终镜像

2. 核心交互: COPY --from=ubuntu / /

两个阶段通过COPY --from=ubuntu / /指令建立连接:

  • 第一阶段(ubuntu)对官方ubuntu:24.04进行修改(如删除/etc/localtime、修改用户shell、移除login工具等),生成一个 "预处理后的 Ubuntu 文件系统"。

  • 第二阶段(scratch)是完全空白的镜像,通过COPY指令将第一阶段的整个根目录(/)复制到当前阶段,相当于 "继承" 了第一阶段的文件系统,但不包含第一阶段的构建历史和冗余层。

3. 这样设计的目的

(1)精简最终镜像体积

官方ubuntu:24.04镜像包含大量冗余文件(如login工具、不必要的配置文件),第一阶段通过rmapt remove清理这些文件,再复制到scratch阶段,避免最终镜像携带无用内容。

(2)定制基础环境

第一阶段的修改(如修改用户shellnologin、删除/etc/localtime)会被保留到最终镜像中,实现对基础系统的定制化,而无需在最终阶段重复执行这些操作。

(3)隔离构建依赖

多阶段构建可以将 "构建工具" 和 "运行时环境" 分离。例如,若第一阶段需要安装编译工具(如gcc),完成编译后,仅将产物复制到最终阶段,避免最终镜像包含编译工具。(本例中未体现编译过程,但核心逻辑一致)

4. 与单阶段构建的区别

如果用单阶段构建(仅FROM ubuntu:24.04),rmapt remove的操作会产生新的镜像层,但原文件仍可能残留在底层镜像中(Docker 镜像的 "写时复制" 特性)。而通过scratch阶段复制,能彻底丢弃底层冗余,实现真正的精简。

总结

两个FROM指令通过 "多阶段构建" 形成 "预处理→复制→再加工" 的流水线:

  • 第一阶段(ubuntu)负责 "净化和定制基础系统";

  • 第二阶段(scratch)负责 "继承净化后的系统,并继续安装应用依赖",最终产出一个精简、定制化的镜像。 这种设计是 Docker 最佳实践之一,尤其适合需要极小化镜像和定制基础环境的场景。

    这种设计是 Docker 最佳实践之一,尤其适合需要极小化镜像和定制基础环境的场景。

相关推荐
努力的小雨4 小时前
还在为调试提示词头疼?一个案例教你轻松上手!
后端
魔都吴所谓4 小时前
【go】语言的匿名变量如何定义与使用
开发语言·后端·golang
陈佬昔没带相机5 小时前
围观前后端对接的 TypeScript 最佳实践,我们缺什么?
前端·后端·api
Livingbody7 小时前
大模型微调数据集加载和分析
后端
Livingbody7 小时前
第一次免费使用A800显卡80GB显存微调Ernie大模型
后端
Goboy8 小时前
Java 使用 FileOutputStream 写 Excel 文件不落盘?
后端·面试·架构
Goboy8 小时前
讲了八百遍,你还是没有理解CAS
后端·面试·架构
麦兜*8 小时前
大模型时代,Transformer 架构中的核心注意力机制算法详解与优化实践
jvm·后端·深度学习·算法·spring·spring cloud·transformer
树獭叔叔8 小时前
Python 多进程与多线程:深入理解与实践指南
后端·python
阿华的代码王国8 小时前
【Android】PopupWindow实现长按菜单
android·xml·java·前端·后端