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

相关推荐
争不过朝夕,又念着往昔19 分钟前
Go语言反射机制详解
开发语言·后端·golang
绝无仅有2 小时前
企微审批对接错误与解决方案
后端·算法·架构
Super Rookie2 小时前
Spring Boot 企业项目技术选型
java·spring boot·后端
来自宇宙的曹先生2 小时前
用 Spring Boot + Redis 实现哔哩哔哩弹幕系统(上篇博客改进版)
spring boot·redis·后端
expect7g2 小时前
Flink-Checkpoint-1.源码流程
后端·flink
00后程序员2 小时前
Fiddler中文版如何提升API调试效率:本地化优势与开发者实战体验汇总
后端
用户8122199367223 小时前
C# .Net Core零基础从入门到精通实战教程全集【190课】
后端
lzzy_lx_20893 小时前
Spring Boot登录认证实现学习心得:从皮肤信息系统项目中学到的经验
java·spring boot·后端
前端付豪4 小时前
21、用 Python + Pillow 实现「朋友圈海报图生成器」📸(图文合成 + 多模板 + 自动换行)
后端·python