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 最佳实践之一,尤其适合需要极小化镜像和定制基础环境的场景。

相关推荐
用户2986985301422 分钟前
.NET 文档自动化:Spire.Doc 设置奇偶页页眉/页脚的最佳实践
后端·c#·.net
序安InToo1 小时前
第6课|注释与代码风格
后端·操作系统·嵌入式
xyy1231 小时前
C#: Newtonsoft.Json 到 System.Text.Json 迁移避坑指南
后端
洋洋技术笔记1 小时前
Spring Boot Web MVC配置详解
spring boot·后端
JxWang051 小时前
VS Code 配置 Markdown 环境
后端
navms1 小时前
搞懂线程池,先把 Worker 机制啃明白
后端
JxWang051 小时前
离线数仓的优化及重构
后端
Nyarlathotep01131 小时前
gin01:初探gin的启动
后端·go
JxWang051 小时前
安卓手机配置通用多屏协同及自动化脚本
后端
JxWang051 小时前
Windows Terminal 配置 oh-my-posh
后端