What Are Docker Image Layers?
Docker images consist of multiple layers that collectively provide the content you see in your containers. But what actually is a layer, and how does it differ from a complete image?
In this article you’ll learn how to distinguish these two concepts and why the difference matters. While you can use Docker without a thorough understanding of layers, having an awareness of their purpose will help you identify optimization opportunities.
What’s an Image?
A Docker “image” behaves like a template from which consistent containers can be created. If Docker was a traditional virtual machine, the image could be likened to the ISO used to install your VM. This isn’t a robust comparison, as Docker differs from VMs in terms of both concept and implementation, but it’s a useful starting point nonetheless.
Images define the initial filesystem state of new containers. They bundle your application’s source code and its dependencies into a self-contained package that’s ready to use with a container runtime. Within the image, filesystem content is represented as multiple independent layers.
What are Layers?
Layers are a result of the way Docker images are built. Each step in a Dockerfile creates a new “layer” that’s essentially a diff of the filesystem changes since the last step. Metadata instructions such as LABEL and MAINTAINER do not create layers because they don’t affect the filesystem.
This image has two instructions (COPY and RUN) so it’ll create two layers:
FROM ubuntu:latest
COPY foo.txt /foo.txt
RUN date > /built-on.txt
- The first step copies foo.txt into a new layer that’s based on the ubuntu:latest image.
- The second step runs the date command and pipes its output into a file. This creates a second layer that’s based on the previous one.
Create foo.txt in your working directory:
$ echo "Hello World" > foo.txt
Now build the sample image:
$ docker build . -t demo:latest
Sending build context to Docker daemon 2.56kB
Step 1/3 : FROM ubuntu:latest---> df5de72bdb3b
Step 2/3 : COPY foo.txt /foo.txt---> 4932aede6a15
Step 3/3 : RUN date > /built-on.txt---> Running in 91d260fc2e68
Removing intermediate container 91d260fc2e68---> 6f653c6a60fa
Successfully built 6f653c6a60fa
Successfully tagged foo:latest
Each build step emits the ID of the created layer. The last step’s layer becomes the final image so it gets tagged with foo:latest.
The sequence reveals that layers are valid Docker images. Although the term “layer” isn’t normally used to refer to a tagged image, all tagged images are technically just layers with an identifier assigned.
You can start a container from an intermediate layer’s image:
$ docker run -it 4932aede6a15 sh
# cat /foo.txt
Hello World
# cat /built-on.txt
cat: /built-on.txt: No such file or directory
This example starts a container from the layer created by the second build step. foo.txt is available in the container but built-on.txt doesn’t exist because it’s not added until the third step. That file’s only available in the filesystems of subsequent layers.
The Role of Layers
Layers contain the changes created by a build step, relative to the previous layer in the Dockerfile. FROM instructions are a special case that reference the final layer of an existing image.
Layers allow build steps to be cached to avoid redundant work. Docker can skip unchanged instructions in your Dockerfile by reusing the previously created layer. It bases the next step on that existing layer, instead of building a new one.
You can see this by modifying your Dockerfile as follows:
FROM ubuntu:latest
COPY foo.txt /foo.txt
RUN date +%Y-%m-%d > /built-on.txt
The third build step has changed. Now rebuild your image:
$ docker build . -t demo:latest
Sending build context to Docker daemon 3.584kB
Step 1/3 : FROM ubuntu:latest---> df5de72bdb3b
Step 2/3 : COPY foo.txt /foo.txt---> Using cache---> 4932aede6a15
Step 3/3 : RUN date +%Y-%m-%d > /built-on.txt---> Running in 2b91ec0462c4
Removing intermediate container 2b91ec0462c4---> c6647ff378c1
Successfully built c6647ff378c1
Successfully tagged demo:latest
The second build step shows as Using cache and produces the same layer ID. Docker could skip building this layer as it was already created earlier and foo.txt hasn’t changed since the first build.
This caching only works up to the point a layer is modified. All the steps after that layer will need to be rebuilt too so they’re based on the new filesystem revision.
Layers and Pull Operations
Another benefit of layers is how they enable partial image pulls. Once you’ve downloaded a few images to your machine, you’ll often find new pulls can skip some layers that you already have. This image contains 13 layers but only six had to be downloaded by the pull operation:
docker pull php:8.0-apache
8.0-apache: Pulling from library/php
7a6db449b51b: Already exists
ad2afdb99a9d: Already exists
dbc5aa907229: Already exists
82f252ab4ad1: Already exists
bf5b34fc9894: Already exists
6161651d3d95: Already exists
cf2adf296ef1: Already exists
f0d7c5221e44: Pull complete
f647198f6316: Pull complete
c37afe1da4e5: Pull complete
09c93531cbca: Pull complete
fef371007dd3: Pull complete
52043dbb1c06: Pull complete
Digest: sha256:429889e8f9eac0a806a005b0728a004303b0d49d77b09496d39158707abd6280
Status: Downloaded newer image for php:8.0-apache
docker.io/library/php:8.0-apache
The other layers were already present on the Docker host so they could be reused. This improves performance and avoids wasting network bandwidth.
Inspecting Image Layers
You can list the layers within an image by running the docker image history command. Each layer displays the ID of the created image and the Dockerfile instruction that caused the change. You can see the total size of the content within the layer too.
$ docker image history
IMAGE CREATED CREATED BY SIZE COMMENT
6f653c6a60fa 4 minutes ago /bin/sh -c date > /built-on.txt 29B
f8420d1a96f3 4 minutes ago /bin/sh -c #(nop) COPY file:a5630a7506b26a37... 0B
df5de72bdb3b 4 weeks ago /bin/sh -c #(nop) CMD ["bash"] 0B
<missing> 4 weeks ago /bin/sh -c #(nop) ADD file:396eeb65c8d737180... 77.8MB
The last layer displays as because it refers to a layer within the ubuntu:latest base image. This is not available locally, as only the final layer of the base image (df5de72bdb3b) gets pulled down during builds. There’s no need to independently pull all the intermediate layers when you want to use a specific image.
Summary
Docker images and layers are generally interchangeable terms. A layer is an image and an image is formed from one or more layers. The major difference lies in tags: an image will be tagged and designed for end users, while the term “layer” normally refers to the untagged intermediate images created as part of a build operation. These aren’t visible unless you go looking for them.
There’s one more topic that relates to layers: running containers add an extra writable layer on top of their image. Layers sourced from the container’s image are read-only so filesystem modifications made by the container target its ephemeral writable layer. The writable layer gets discarded when the container’s stopped or deleted.
相关文章:
What Are Docker Image Layers?
Docker images consist of multiple layers that collectively provide the content you see in your containers. But what actually is a layer, and how does it differ from a complete image? In this article you’ll learn how to distinguish these two concepts and…...
范数详解-torch.linalg.norm计算实例
文章目录 二范数F范数核范数无穷范数L1范数L2范数 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 范数是一种数学概念,可以将向量或矩阵映射到非负实数上,通常被…...
postgresdb备份脚本
以下是一个简单的postgresdb备份脚本示例: 复制 #!/bin/bash # 设置备份目录和文件名 BACKUP_DIR/path/to/backup BACKUP_FILEdb_backup_$(date %F_%H-%M-%S).sql # 设置数据库连接参数 DB_HOSTlocalhost DB_PORT5432 DB_NAMEmydatabase DB_USERmyusername DB_PA…...
MATLAB程序员投简历的技巧解析,如何写出有亮点的简历
如果你想在简历中展示你的项目经验,一定要有亮点。一个导出的 Excel 文件过大导致浏览器卡顿的例子就是一个很好的亮点。你可以在简历中写明这个例子。如果面试官问起,可以用浏览器的原理来解释。浏览器内核可以简单地分为以下 5 个线程:GUI …...
颜色空间转换RGB-YCbCr
颜色空间 颜色空间(Color Space)是描述颜色的一种方式,它是一个由数学模型表示的三维空间,通常用于将数字表示的颜色转换成可见的颜色。颜色空间的不同取决于所选的坐标轴和原点,以及用于表示颜色的色彩模型。在计算机…...
年薪40万程序员辞职炒股,把一年工资亏光了,得了抑郁症,太惨了
年薪40万的程序员辞职全职炒股 把一年的工资亏光了 得了抑郁症 刚才在网上看了一篇文章 是一位北京的一位在互联网 大厂上班的程序员 在去年就是股市行情比较好的时候 他买了30多万股票 结果连续三个月都赚钱 然后呢 他是就把每天就996这种工作就辞掉了 然后在家全是炒股 感觉炒…...
10分钟如何轻松掌握JMeter使用方法?
目录 引言 安装jmeter HTTP信息头管理器 JMeter断言 HTTP请求默认值来代替所有的域名与端口 JSON提取器来替换变量 结语 引言 想要了解网站或应用程序的性能极限,JMeter是一个不可或缺的工具。但是,对于初学者来说,该如何上手使用JMe…...
[NLP]如何训练自己的大型语言模型
简介 大型语言模型,如OpenAI的GPT-4或Google的PaLM,已经席卷了人工智能领域。然而,大多数公司目前没有能力训练这些模型,并且完全依赖于只有少数几家大型科技公司提供技术支持。 在Replit,我们投入了大量资源来建立从…...
LeetCode1047. 删除字符串中的所有相邻重复项
1047. 删除字符串中的所有相邻重复项 给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。 在 S 上反复执行重复项删除操作,直到无法继续删除。 在完成所有重复项删除操作后返回最终的字符串。答案保证唯一…...
3。数据结构(3)
嵌入式软件开发第三部分,各类常用的数据结构及扩展,良好的数据结构选择是保证程序稳定运行的关键,(1)部分包括数组,链表,栈,队列。(2)部分包括树,…...
QT停靠窗口QDockWidget类
QT停靠窗口QDockWidget类 QDockWidget类简介函数和方法讲解 QDockWidget类简介 QDockWidget 类提供了一个部件,它可以停靠在 QMainWindow 内或作为桌面上的顶级窗口浮动。 QDockWidget 提供了停靠窗口部件的概念,也称为工具面板或实用程序窗口。 停靠窗…...
【LeetCode】139. 单词拆分
139. 单词拆分(中等) 思路 首先将大问题分解成小问题: 前 i 个字符的子串,能否分解成单词;剩余子串,是否为单个单词; 动态规划的四个步骤: 确定 dp 数组以及下标的含义 dp[i] 表示 s…...
【三维重建】NeRF原理+代码讲解
文章目录 一、技术原理1.概览2.基于神经辐射场(Neural Radiance Field)的体素渲染算法3.体素渲染算法4.位置信息编码(Positional encoding)5.多层级体素采样 二、代码讲解1.数据读入2.创建nerf1.计算焦距focal与其他设置2.get_emb…...
IntelliJ IDEA 社区版2021.3配置SpringBoot项目详细教程及错误解决方法
目录 一、SpringBoot的定义 二、Spring Boot 优点 三、创建一个springboot的项目 四、使用IDEA创建SpringBoot失败案例 一、SpringBoot的定义 Spring 的诞⽣是为了简化 Java 程序的开发的,⽽ Spring Boot 的诞⽣是为了简化 Spring 程序开发的。 Spring Boot 翻…...
Qt中QDebug的使用
QDebug类为调试信息(debugging information)提供输出流。它的声明在<QDebug>中,实现在Core模块中。将调试或跟踪信息(debugging or tracing information)写出到device, file, string or console时都会使用QDebug。 此类的成员函数参考:https://doc…...
vue使用路由的query配置项时如何清除地址栏的参数
写vue项目时,如果想通过路由的query配置项把参数从一个组件传到另一个组件,但是又不希望?idxxx显示在地址栏(如:http://localhost:8080/test?idxxx的?idxxx),该怎么做: 举一个案例࿱…...
Redis-列表(List)
Redis列表(List) 介绍 单键多值Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)它的底层实际是个双向链表,对两端的操作性能很高,通过索…...
ripro主题修改教程-首页搜索框美化教程
先看效果图: 我们来看怎么实现: 1、找到wp-content/themes/ripro/assets/css/diy.css并将下面的内容整体复制进去并保存 /*首页搜索框*/ .bgcolor-fff {background-color: #fff; } .row,.navbar .menu-item-mega>.sub-menu{margin-left:-10px;margin-right:-10px;} .home…...
写作业用白光还是暖光?盘点色温4000K的护眼台灯
台灯的白光或者暖光指的是台灯的色温,低色温的光线看起来发黄发红,高色温的光线发白发蓝。 如果灯光的光源是高品质光源,本身没有蓝光问题,那么色温的选择对护眼的影响是比较少的,更多的是对人学习工作状态,…...
Java时间类(一)-- SimpleDateFormat类
目录 1. SimpleDateFormat的构造方法: 时间模式字母: 2. SimpleDateFormat的常用方法: “工欲善其事,必先利其器”。学习时间类之前,需要先学习SimpleDateFormat类。 java.text.SimpleDateFormat类是以与语言环境有关的方式来格式...
观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
第7篇:中间件全链路监控与 SQL 性能分析实践
7.1 章节导读 在构建数据库中间件的过程中,可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中,必须做到: 🔍 追踪每一条 SQL 的生命周期(从入口到数据库执行)&#…...
深入浅出Diffusion模型:从原理到实践的全方位教程
I. 引言:生成式AI的黎明 – Diffusion模型是什么? 近年来,生成式人工智能(Generative AI)领域取得了爆炸性的进展,模型能够根据简单的文本提示创作出逼真的图像、连贯的文本,乃至更多令人惊叹的…...
C++实现分布式网络通信框架RPC(2)——rpc发布端
有了上篇文章的项目的基本知识的了解,现在我们就开始构建项目。 目录 一、构建工程目录 二、本地服务发布成RPC服务 2.1理解RPC发布 2.2实现 三、Mprpc框架的基础类设计 3.1框架的初始化类 MprpcApplication 代码实现 3.2读取配置文件类 MprpcConfig 代码实现…...
sshd代码修改banner
sshd服务连接之后会收到字符串: SSH-2.0-OpenSSH_9.5 容易被hacker识别此服务为sshd服务。 是否可以通过修改此banner达到让人无法识别此服务的目的呢? 不能。因为这是写的SSH的协议中的。 也就是协议规定了banner必须这么写。 SSH- 开头,…...
