<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>container-image on Jack Henschel's Blog</title><link>https://blog.cubieserver.de/tags/container-image/</link><description>Recent content in container-image on Jack Henschel's Blog</description><generator>Hugo -- gohugo.io</generator><language>en-US</language><lastBuildDate>Thu, 06 Jun 2024 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.cubieserver.de/tags/container-image/index.xml" rel="self" type="application/rss+xml"/><item><title>Tools for analyzing and working with container images</title><link>https://blog.cubieserver.de/2024/tools-for-analyzing-and-working-with-container-images/</link><pubDate>Thu, 06 Jun 2024 00:00:00 +0000</pubDate><guid>https://blog.cubieserver.de/2024/tools-for-analyzing-and-working-with-container-images/</guid><description>&lt;p>In this post I&amp;rsquo;d like to share some tools from my toolbox for working with container images (Docker/OCI).
I specifically excluded tools for &lt;em>building&lt;/em> container images (Buildkit, buildah, kaniko &amp;amp; friends).&lt;/p>
&lt;h3 id="what-is-a-container-image">
&lt;a href="#what-is-a-container-image">#
&lt;/a>&amp;nbsp;What is a container image?
&lt;/h3>
&lt;p>Before we get to the tools, let&amp;rsquo;s first take a minute to understand what a container image actually is.
This will allow us to better understand what these tools do and how they can help us.&lt;/p>
&lt;p>In a nutshell, a container &lt;em>image&lt;/em> is a collection of &lt;em>layers&lt;/em> alongside some &lt;em>configuration&lt;/em> metadata which are tied together by an &lt;em>image manifest&lt;/em>.
The layers contain files and directories, which are stacked on top of each other to form the final filesystem for the container.
The principal is similar to a &lt;em>Git&lt;/em> repository: each repository is made up of one or more commits (= &lt;em>layers&lt;/em>), a j&lt;code>.git/config&lt;/code> (= &lt;em>configuration&lt;/em>) and an index (= &lt;em>manifest&lt;/em>).
The container image format was initially developed by &lt;a href="https://www.docker.com/">Docker&lt;/a>, but has been spun out into the dedicated &lt;a href="https://opencontainers.org/">Open Container Initiative&lt;/a> project to help with standardization and interoperability.
These days the &lt;a href="https://github.com/opencontainers/image-spec/blob/main/spec.md">OCI image specification&lt;/a> formally defines what an image consists of and is supported by many tools in the cloud native ecosystem.&lt;/p>
&lt;p>&lt;img src="container-image-min.svg" alt="">&lt;/p>
&lt;p>&lt;em>Sidenote:&lt;/em> the OCI also defines the &lt;a href="https://github.com/opencontainers/distribution-spec/blob/main/spec.md">Distribution Specification&lt;/a> (which API clients and servers need to implement for uploading and downloading container images) as well as the &lt;a href="https://github.com/opencontainers/runtime-spec/blob/main/spec.md">Runtime Specification&lt;/a> (how a container should be run).&lt;/p>
&lt;p>Let&amp;rsquo;s look at a practical example (all subsequent &lt;code>podman&lt;/code> command can be substituted with &lt;code>docker&lt;/code>):&lt;/p>
&lt;div class="highlight">&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;">&lt;tr>&lt;td style="vertical-align:top;padding:0;margin:0;border:0;">
&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sh" data-lang="sh">$ mkdir /tmp/container-tools
$ cd /tmp/container-tools
$ podman image pull docker.io/library/httpd:latest
Trying to pull docker.io/library/httpd:latest...
Getting image source signatures
Copying blob ea83e81966d6 ... &lt;span style="color:#66d9ef">done&lt;/span>
Copying blob b0a0cf830b12 ... &lt;span style="color:#66d9ef">done&lt;/span>
Copying blob 4f4fb700ef54 ... &lt;span style="color:#66d9ef">done&lt;/span>
Copying blob 943a2b3cf551 ... &lt;span style="color:#66d9ef">done&lt;/span>
Copying blob 851c52adaa9b ... &lt;span style="color:#66d9ef">done&lt;/span>
Copying blob 39d9f60535a6 ... &lt;span style="color:#66d9ef">done&lt;/span>
Copying config 67c2fc9e3d ... &lt;span style="color:#66d9ef">done&lt;/span>
Writing manifest to image destination
67c2fc9e3d849b21a35b4c96f5ad8ec4dc9b73ca44c56537039e8c6f3054db0a
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>The previous command downloaded the most recent version of the Apache httpd container image from DockerHub.
Based on the progressive download output we can already see that the container image is not &amp;ldquo;one file&amp;rdquo;, but is made up of multiple parts (referred to as &lt;em>blobs&lt;/em> in the output above).&lt;/p>
&lt;p>The image is now stored locally on the machine, but the exact location will vary depending on the container manager (Docker, Podman, &amp;hellip;) and its configuration.
Let&amp;rsquo;s extract the contents of the container image into an empty directory:&lt;/p>
&lt;div class="highlight">&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;">&lt;tr>&lt;td style="vertical-align:top;padding:0;margin:0;border:0;">
&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">22
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">23
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">24
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">25
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">26
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">27
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">28
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">29
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">30
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">31
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">32
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">33
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">34
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">35
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">36
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">37
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">38
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">39
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sh" data-lang="sh">$ mkdir /tmp/httpd &lt;span style="color:#f92672">&amp;amp;&amp;amp;&lt;/span> cd /tmp/httpd
$ podman image save docker.io/library/httpd:latest | tar x
$ tree
.
├── 30bc0a59d494d75238f1f9d26e3851eb33debbfca69ed5dac18588bdcb58d9d4
│   ├── json
│   ├── layer.tar -&amp;gt; ../53920c8b9c11c3f431a7f096a6a496f587eec1ccbc3b9e9649470db799c96758.tar
│   └── VERSION
├── 46176a0cbe9f3e95a08e3914ef9f4ac33fb1d412c9bacf2d1217616f76077fad.tar
├── 52ec5a4316fadc09a4a51f82b8d7b66ead0d71bea4f75e81e25b4094c4219061.tar
├── 53920c8b9c11c3f431a7f096a6a496f587eec1ccbc3b9e9649470db799c96758.tar
├── 5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef.tar
├── 67c2fc9e3d849b21a35b4c96f5ad8ec4dc9b73ca44c56537039e8c6f3054db0a.json
├── 7b341f868c2e467ddb56f7dfcbe82578403faa3da4ae0cb264048f3fa7a9bacd
│   ├── json
│   ├── layer.tar -&amp;gt; ../5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef.tar
│   └── VERSION
├── a1f21c4adbc031095cd0bf494d36e6d2f7c8c0a4fb0e8f22ff559f3e4b436e66
│   ├── json
│   ├── layer.tar -&amp;gt; ../dba1169a4ef830544ed14026d745670ee754a929e251440482009a5e89d4f20c.tar
│   └── VERSION
├── a2ba897b57547df4c74318915ba74bac4c5603d3ed56ea70eb7397914479d033
│   ├── json
│   ├── layer.tar -&amp;gt; ../ed8b961e754fdc176a3307cc94471a8c7db19edfcbce503deeb40d0043af2f44.tar
│   └── VERSION
├── d4112ecc8ff8a228860a3851d8cdf391987fc47b0c1ffa9e3ddbc1c744da4b16
│   ├── json
│   ├── layer.tar -&amp;gt; ../46176a0cbe9f3e95a08e3914ef9f4ac33fb1d412c9bacf2d1217616f76077fad.tar
│   └── VERSION
├── dba1169a4ef830544ed14026d745670ee754a929e251440482009a5e89d4f20c.tar
├── e6fa7777a000792ac871b6ab8c18b5dd6778dbe61537b3864e4aa50445c45d2c
│   ├── json
│   ├── layer.tar -&amp;gt; ../52ec5a4316fadc09a4a51f82b8d7b66ead0d71bea4f75e81e25b4094c4219061.tar
│   └── VERSION
├── ed8b961e754fdc176a3307cc94471a8c7db19edfcbce503deeb40d0043af2f44.tar
├── manifest.json
└── repositories
&lt;span style="color:#ae81ff">7&lt;/span> directories, &lt;span style="color:#ae81ff">27&lt;/span> files
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>The image manifest (&lt;code>manifest.json&lt;/code>) is the file that ties everything together, let&amp;rsquo;s take a look at it:&lt;/p>
&lt;div class="highlight">&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;">&lt;tr>&lt;td style="vertical-align:top;padding:0;margin:0;border:0;">
&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sh" data-lang="sh">$ jq . manifest.json
&lt;span style="color:#f92672">[&lt;/span>
&lt;span style="color:#f92672">{&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;Config&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;67c2fc9e3d849b21a35b4c96f5ad8ec4dc9b73ca44c56537039e8c6f3054db0a.json&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;RepoTags&amp;#34;&lt;/span>: &lt;span style="color:#f92672">[&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;docker.io/library/httpd:latest&amp;#34;&lt;/span>
&lt;span style="color:#f92672">]&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;Layers&amp;#34;&lt;/span>: &lt;span style="color:#f92672">[&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;52ec5a4316fadc09a4a51f82b8d7b66ead0d71bea4f75e81e25b4094c4219061.tar&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;46176a0cbe9f3e95a08e3914ef9f4ac33fb1d412c9bacf2d1217616f76077fad.tar&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef.tar&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;53920c8b9c11c3f431a7f096a6a496f587eec1ccbc3b9e9649470db799c96758.tar&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;ed8b961e754fdc176a3307cc94471a8c7db19edfcbce503deeb40d0043af2f44.tar&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;dba1169a4ef830544ed14026d745670ee754a929e251440482009a5e89d4f20c.tar&amp;#34;&lt;/span>
&lt;span style="color:#f92672">]&lt;/span>
&lt;span style="color:#f92672">}&lt;/span>
&lt;span style="color:#f92672">]&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>It tells us where we can find the configuration (&lt;code>Config&lt;/code>) of the container image and where we can find the layers.
Notice that &lt;code>layers&lt;/code> is an array: the layers need to be assembled in the correct order to get the correct result.
It&amp;rsquo;s also interesting to observe that all referenced files use &lt;a href="https://en.wikipedia.org/wiki/Content-addressable_storage">content-addressable storage&lt;/a>, i.e. the name of the files corresponds to their SHA256 checksum.
The first advantage is that we can easily check if any errors occurred during the download (if that was the cause, the filename and checksum would not match):&lt;/p>
&lt;div class="highlight">&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;">&lt;tr>&lt;td style="vertical-align:top;padding:0;margin:0;border:0;">
&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">2
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">3
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">4
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">5
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">6
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">7
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">8
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sh" data-lang="sh">$ sha256sum *.json *.tar
67c2fc9e3d849b21a35b4c96f5ad8ec4dc9b73ca44c56537039e8c6f3054db0a 67c2fc9e3d849b21a35b4c96f5ad8ec4dc9b73ca44c56537039e8c6f3054db0a.json
46176a0cbe9f3e95a08e3914ef9f4ac33fb1d412c9bacf2d1217616f76077fad 46176a0cbe9f3e95a08e3914ef9f4ac33fb1d412c9bacf2d1217616f76077fad.tar
52ec5a4316fadc09a4a51f82b8d7b66ead0d71bea4f75e81e25b4094c4219061 52ec5a4316fadc09a4a51f82b8d7b66ead0d71bea4f75e81e25b4094c4219061.tar
53920c8b9c11c3f431a7f096a6a496f587eec1ccbc3b9e9649470db799c96758 53920c8b9c11c3f431a7f096a6a496f587eec1ccbc3b9e9649470db799c96758.tar
5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef 5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef.tar
dba1169a4ef830544ed14026d745670ee754a929e251440482009a5e89d4f20c dba1169a4ef830544ed14026d745670ee754a929e251440482009a5e89d4f20c.tar
ed8b961e754fdc176a3307cc94471a8c7db19edfcbce503deeb40d0043af2f44 ed8b961e754fdc176a3307cc94471a8c7db19edfcbce503deeb40d0043af2f44.tar
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>The second advantage is that it allows &lt;em>sharing layers&lt;/em> between container images.
For example if two container images are built from the same base image, that particular base layer only needs to be stored once (both in the container registry and on the local machine) as well transmitted once (the check can be carried out before downloading the layers).&lt;/p>
&lt;p>The configuration file (in this case &lt;code>67c2fc9e3d849b21a35b4c96f5ad8ec4dc9b73ca44c56537039e8c6f3054db0a.json&lt;/code>) contains information about how and when the image was built (&lt;code>history&lt;/code>), which platform it is compatible with (&lt;code>architecture&lt;/code>, &lt;code>os&lt;/code>) and how the container should be run (elements under &lt;code>config&lt;/code>).&lt;/p>
&lt;div class="highlight">&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;">&lt;tr>&lt;td style="vertical-align:top;padding:0;margin:0;border:0;">
&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 10
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 11
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 12
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 13
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 14
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 15
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 16
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 17
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 18
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 19
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 20
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 21
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 22
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 23
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 24
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 25
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 26
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 27
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 28
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 29
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 30
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 31
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 32
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 33
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 34
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 35
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 36
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 37
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 38
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 39
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 40
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 41
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 42
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 43
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 44
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 45
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 46
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 47
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 48
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 49
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 50
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 51
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 52
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 53
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 54
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 55
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 56
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 57
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 58
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 59
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 60
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 61
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 62
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 63
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 64
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 65
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 66
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 67
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 68
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 69
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 70
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 71
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 72
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 73
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 74
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 75
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 76
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 77
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 78
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 79
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 80
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 81
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 82
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 83
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 84
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 85
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 86
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 87
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 88
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 89
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 90
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 91
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 92
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 93
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 94
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 95
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 96
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 97
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 98
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 99
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">100
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">101
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">102
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">103
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">104
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">105
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">106
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">107
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">108
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">109
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">110
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">111
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">112
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">113
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">114
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">115
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">116
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">117
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">118
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">119
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sh" data-lang="sh">$ jq . 67c2fc9e3d849b21a35b4c96f5ad8ec4dc9b73ca44c56537039e8c6f3054db0a.json
&lt;span style="color:#f92672">{&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;architecture&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;amd64&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;config&amp;#34;&lt;/span>: &lt;span style="color:#f92672">{&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;ExposedPorts&amp;#34;&lt;/span>: &lt;span style="color:#f92672">{&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;80/tcp&amp;#34;&lt;/span>: &lt;span style="color:#f92672">{}&lt;/span>
&lt;span style="color:#f92672">}&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;Env&amp;#34;&lt;/span>: &lt;span style="color:#f92672">[&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;PATH=/usr/local/apache2/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;HTTPD_PREFIX=/usr/local/apache2&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;HTTPD_VERSION=2.4.59&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;HTTPD_SHA256=ec51501ec480284ff52f637258135d333230a7d229c3afa6f6c2f9040e321323&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;HTTPD_PATCHES=&amp;#34;&lt;/span>
&lt;span style="color:#f92672">]&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;Cmd&amp;#34;&lt;/span>: &lt;span style="color:#f92672">[&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;httpd-foreground&amp;#34;&lt;/span>
&lt;span style="color:#f92672">]&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;WorkingDir&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;/usr/local/apache2&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;StopSignal&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;SIGWINCH&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;ArgsEscaped&amp;#34;&lt;/span>: true
&lt;span style="color:#f92672">}&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;created&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;2024-04-05T21:49:16Z&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;history&amp;#34;&lt;/span>: &lt;span style="color:#f92672">[&lt;/span>
&lt;span style="color:#f92672">{&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;created&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;2024-04-05T21:49:16Z&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;created_by&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;/bin/sh -c #(nop) ADD file:4b1be1de1a1e5aa608c688cad2824587262081866180d7368feb79d33ca05953 in / &amp;#34;&lt;/span>
&lt;span style="color:#f92672">}&lt;/span>,
&lt;span style="color:#f92672">{&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;created&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;2024-04-05T21:49:16Z&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;created_by&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;/bin/sh -c #(nop) CMD [\&amp;#34;bash\&amp;#34;]&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;empty_layer&amp;#34;&lt;/span>: true
&lt;span style="color:#f92672">}&lt;/span>,
&lt;span style="color:#f92672">{&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;created&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;2024-04-05T21:49:16Z&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;created_by&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;ENV HTTPD_PREFIX=/usr/local/apache2&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;comment&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;buildkit.dockerfile.v0&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;empty_layer&amp;#34;&lt;/span>: true
&lt;span style="color:#f92672">}&lt;/span>,
&lt;span style="color:#f92672">{&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;created&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;2024-04-05T21:49:16Z&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;created_by&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;ENV PATH=/usr/local/apache2/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;comment&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;buildkit.dockerfile.v0&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;empty_layer&amp;#34;&lt;/span>: true
&lt;span style="color:#f92672">}&lt;/span>,
&lt;span style="color:#f92672">{&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;created&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;2024-04-05T21:49:16Z&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;created_by&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;RUN /bin/sh -c mkdir -p \&amp;#34;&lt;/span>$HTTPD_PREFIX&lt;span style="color:#e6db74">\&amp;#34; \t&amp;amp;&amp;amp; chown www-data:www-data \&amp;#34;&lt;/span>$HTTPD_PREFIX&lt;span style="color:#e6db74">\&amp;#34; # buildkit&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;comment&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;buildkit.dockerfile.v0&amp;#34;&lt;/span>
&lt;span style="color:#f92672">}&lt;/span>,
&lt;span style="color:#f92672">{&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;created&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;2024-04-05T21:49:16Z&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;created_by&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;WORKDIR /usr/local/apache2&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;comment&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;buildkit.dockerfile.v0&amp;#34;&lt;/span>
&lt;span style="color:#f92672">}&lt;/span>,
&lt;span style="color:#f92672">{&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;created&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;2024-04-05T21:49:16Z&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;created_by&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;RUN /bin/sh -c set -eux; \tapt-get update; \tapt-get install -y --no-install-recommends \t\tca-certificates \t\tlibaprutil1-ldap \t\tlibldap-common \t; \trm -rf /var/lib/apt/lists/* # buildkit&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;comment&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;buildkit.dockerfile.v0&amp;#34;&lt;/span>
&lt;span style="color:#f92672">}&lt;/span>,
&lt;span style="color:#f92672">{&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;created&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;2024-04-05T21:49:16Z&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;created_by&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;ENV HTTPD_VERSION=2.4.59&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;comment&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;buildkit.dockerfile.v0&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;empty_layer&amp;#34;&lt;/span>: true
&lt;span style="color:#f92672">}&lt;/span>,
&lt;span style="color:#f92672">{&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;created&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;2024-04-05T21:49:16Z&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;created_by&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;ENV HTTPD_SHA256=ec51501ec480284ff52f637258135d333230a7d229c3afa6f6c2f9040e321323&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;comment&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;buildkit.dockerfile.v0&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;empty_layer&amp;#34;&lt;/span>: true
&lt;span style="color:#f92672">}&lt;/span>,
&lt;span style="color:#f92672">{&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;created&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;2024-04-05T21:49:16Z&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;created_by&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;ENV HTTPD_PATCHES=&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;comment&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;buildkit.dockerfile.v0&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;empty_layer&amp;#34;&lt;/span>: true
&lt;span style="color:#f92672">}&lt;/span>,
&lt;span style="color:#f92672">{&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;created&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;2024-04-05T21:49:16Z&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;created_by&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;RUN /bin/sh -c set -eux; \t\tsavedAptMark=\&amp;#34;&lt;/span>&lt;span style="color:#66d9ef">$(&lt;/span>apt-mark showmanual&lt;span style="color:#66d9ef">)&lt;/span>&lt;span style="color:#e6db74">\&amp;#34;; \tapt-get update; [...] &amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;comment&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;buildkit.dockerfile.v0&amp;#34;&lt;/span>
&lt;span style="color:#f92672">}&lt;/span>,
&lt;span style="color:#f92672">{&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;created&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;2024-04-05T21:49:16Z&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;created_by&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;STOPSIGNAL SIGWINCH&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;comment&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;buildkit.dockerfile.v0&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;empty_layer&amp;#34;&lt;/span>: true
&lt;span style="color:#f92672">}&lt;/span>,
&lt;span style="color:#f92672">{&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;created&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;2024-04-05T21:49:16Z&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;created_by&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;COPY httpd-foreground /usr/local/bin/ # buildkit&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;comment&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;buildkit.dockerfile.v0&amp;#34;&lt;/span>
&lt;span style="color:#f92672">}&lt;/span>,
&lt;span style="color:#f92672">{&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;created&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;2024-04-05T21:49:16Z&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;created_by&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;EXPOSE map[80/tcp:{}]&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;comment&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;buildkit.dockerfile.v0&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;empty_layer&amp;#34;&lt;/span>: true
&lt;span style="color:#f92672">}&lt;/span>,
&lt;span style="color:#f92672">{&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;created&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;2024-04-05T21:49:16Z&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;created_by&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;CMD [\&amp;#34;httpd-foreground\&amp;#34;]&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;comment&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;buildkit.dockerfile.v0&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;empty_layer&amp;#34;&lt;/span>: true
&lt;span style="color:#f92672">}&lt;/span>
&lt;span style="color:#f92672">]&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;os&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;linux&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;rootfs&amp;#34;&lt;/span>: &lt;span style="color:#f92672">{&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;type&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;layers&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;diff_ids&amp;#34;&lt;/span>: &lt;span style="color:#f92672">[&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;sha256:52ec5a4316fadc09a4a51f82b8d7b66ead0d71bea4f75e81e25b4094c4219061&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;sha256:46176a0cbe9f3e95a08e3914ef9f4ac33fb1d412c9bacf2d1217616f76077fad&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;sha256:53920c8b9c11c3f431a7f096a6a496f587eec1ccbc3b9e9649470db799c96758&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;sha256:ed8b961e754fdc176a3307cc94471a8c7db19edfcbce503deeb40d0043af2f44&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;sha256:dba1169a4ef830544ed14026d745670ee754a929e251440482009a5e89d4f20c&amp;#34;&lt;/span>
&lt;span style="color:#f92672">]&lt;/span>
&lt;span style="color:#f92672">}&lt;/span>
&lt;span style="color:#f92672">}&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Finally, let&amp;rsquo;s take a look at the layers, which are individual archives (&lt;code>.tar&lt;/code>).
&lt;em>Sidenote&lt;/em>: usually these &lt;a href="https://github.com/opencontainers/image-spec/blob/main/layer.md">layers are compressed&lt;/a> with &lt;code>gzip&lt;/code> or &lt;code>zstd&lt;/code> to save space (and time!).
This is not the case here because we locally exported the image, i.e. they have already been decompressed in the process.&lt;/p>
&lt;div class="highlight">&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;">&lt;tr>&lt;td style="vertical-align:top;padding:0;margin:0;border:0;">
&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">22
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">23
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">24
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">25
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">26
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">27
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">28
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sh" data-lang="sh">&lt;span style="color:#75715e"># the base layer (`FROM debian:bookworm-slim`)&lt;/span>
$ tar tvf 52ec5a4316fadc09a4a51f82b8d7b66ead0d71bea4f75e81e25b4094c4219061.tar | wc -l
&lt;span style="color:#ae81ff">4222&lt;/span>
&lt;span style="color:#75715e"># second layer only creates the apache directory&lt;/span>
$ tar tvf 46176a0cbe9f3e95a08e3914ef9f4ac33fb1d412c9bacf2d1217616f76077fad.tar
drwxr-xr-x 0/0 &lt;span style="color:#ae81ff">0&lt;/span> 2024-04-23 17:00 usr/
drwxr-xr-x 0/0 &lt;span style="color:#ae81ff">0&lt;/span> 2024-04-24 06:54 usr/local/
drwxr-xr-x 33/33 &lt;span style="color:#ae81ff">0&lt;/span> 2024-04-24 06:54 usr/local/apache2/
&lt;span style="color:#75715e"># third layer is empty (changing WORKDIR)&lt;/span>
$ tar tvf 5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef.tar | wc -l
&lt;span style="color:#ae81ff">0&lt;/span>
&lt;span style="color:#75715e"># fourth layer adds runtime dependencies, certificates etc.&lt;/span>
$ tar tvf 53920c8b9c11c3f431a7f096a6a496f587eec1ccbc3b9e9649470db799c96758.tar | wc -l
&lt;span style="color:#ae81ff">608&lt;/span>
&lt;span style="color:#75715e"># fifth layer contains the application (apache httpd)&lt;/span>
$ tar tvf ed8b961e754fdc176a3307cc94471a8c7db19edfcbce503deeb40d0043af2f44.tar | wc -l
&lt;span style="color:#ae81ff">735&lt;/span>
&lt;span style="color:#75715e"># final layer adds a script for running apache httpd in the foreground&lt;/span>
$ tar tvf dba1169a4ef830544ed14026d745670ee754a929e251440482009a5e89d4f20c.tar
drwxr-xr-x 0/0 &lt;span style="color:#ae81ff">0&lt;/span> 2024-04-23 17:00 usr/
drwxr-xr-x 0/0 &lt;span style="color:#ae81ff">0&lt;/span> 2024-04-24 06:54 usr/local/
drwxr-xr-x 0/0 &lt;span style="color:#ae81ff">0&lt;/span> 2024-04-24 06:57 usr/local/bin/
-rwxr-xr-x 0/0 &lt;span style="color:#ae81ff">138&lt;/span> 2024-04-24 06:54 usr/local/bin/httpd-foreground
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>For reference you can compare these layers to the &lt;a href="https://github.com/docker-library/httpd/blob/7b7f8cdd958f930766a2238f19046ef92fc14180/2.4/Dockerfile">upstream Dockerfile&lt;/a>.
Notice that not all instructions result in the creation of a new layer.
Instructions like &lt;code>ENV&lt;/code> and &lt;code>STOPSIGNAL&lt;/code> are recorded in the configuration manifest instead, which we looked at before.&lt;/p>
&lt;p>Now we have a basic understanding of the contents of a container image, let&amp;rsquo;s take a look at the toolbox.&lt;/p>
&lt;h3 id="dive">
&lt;a href="#dive">#
&lt;/a>&amp;nbsp;dive
&lt;/h3>
&lt;p>The first tool is called &lt;a href="https://github.com/wagoodman/dive">dive&lt;/a>: an interactive TUI (terminal user interface) tool that effectively automates the process we did above: looking at individual layers of an image and understanding which files were added/removed/modified.
This is super helpful for learning how to write efficient Dockerfiles (i.e. minimal size) and developing confidence on what &lt;em>exactly&lt;/em> is part of the image being built.
Diffing and seeing what files/directories go into each layer is handy to reduce the size of the container image, which in return makes it faster to build, upload and download since less data needs to transferred.&lt;/p>
&lt;div class="highlight">&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;">&lt;tr>&lt;td style="vertical-align:top;padding:0;margin:0;border:0;">
&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">22
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">23
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">24
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">25
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">26
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">27
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">28
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">29
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">30
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">31
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">32
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">33
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">34
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">35
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">36
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">37
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">38
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">39
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">40
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">41
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">42
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">43
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">44
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">45
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">46
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sh" data-lang="sh">$ dive podman://docker.io/library/httpd:latest
┃ ● Current Layer Contents ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
│ Layers ├──────────────────────────────────────────────────────────────────────────── Permission UID:GID Size Filetree
Cmp Size Command -rwxrwxrwx 0:0 &lt;span style="color:#ae81ff">0&lt;/span> B ├── bin → usr/bin
&lt;span style="color:#ae81ff">75&lt;/span> MB FROM 52ec5a4316fadc0 drwxr-xr-x 0:0 &lt;span style="color:#ae81ff">0&lt;/span> B ├── boot
&lt;span style="color:#ae81ff">0&lt;/span> B RUN /bin/sh -c mkdir -p &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$HTTPD_PREFIX&lt;span style="color:#e6db74">&amp;#34;&lt;/span> &lt;span style="color:#f92672">&amp;amp;&amp;amp;&lt;/span> chown www-data:www-data &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$H&lt;span style="color:#e6db74"> drwxr-xr-x 0:0 0 B ├── dev
&lt;/span>&lt;span style="color:#e6db74"> 0 B WORKDIR /usr/local/apache2 drwxr-xr-x 0:0 172 kB ├─⊕ etc
&lt;/span>&lt;span style="color:#e6db74"> 10 MB RUN /bin/sh -c set -eux; apt-get update; apt-get install -y --no-i drwxr-xr-x 0:0 0 B ├── home
&lt;/span>&lt;span style="color:#e6db74"> 62 MB RUN /bin/sh -c set -eux; savedAptMark=&amp;#34;&lt;/span>&lt;span style="color:#66d9ef">$(&lt;/span>apt-mark showmanual&lt;span style="color:#66d9ef">)&lt;/span>&lt;span style="color:#e6db74">&amp;#34;; -rwxrwxrwx 0:0 0 B ├── lib → usr/lib
&lt;/span>&lt;span style="color:#e6db74"> 138 B COPY httpd-foreground /usr/local/bin/ # buildkit -rwxrwxrwx 0:0 0 B ├── lib64 → usr/lib64
&lt;/span>&lt;span style="color:#e6db74"> drwxr-xr-x 0:0 0 B ├── media
&lt;/span>&lt;span style="color:#e6db74"> drwxr-xr-x 0:0 0 B ├── mnt
&lt;/span>&lt;span style="color:#e6db74"> drwxr-xr-x 0:0 0 B ├── opt
&lt;/span>&lt;span style="color:#e6db74"> drwxr-xr-x 0:0 0 B ├── proc
&lt;/span>&lt;span style="color:#e6db74"> drwx------ 0:0 732 B ├─⊕ root
&lt;/span>&lt;span style="color:#e6db74"> drwxr-xr-x 0:0 0 B ├─⊕ run
&lt;/span>&lt;span style="color:#e6db74"> -rwxrwxrwx 0:0 0 B ├── sbin → usr/sbin
&lt;/span>&lt;span style="color:#e6db74">│ Layer Details ├───────────────────────────────────────────────────────────────────── drwxr-xr-x 0:0 0 B ├── srv
&lt;/span>&lt;span style="color:#e6db74"> drwxr-xr-x 0:0 0 B ├── sys
&lt;/span>&lt;span style="color:#e6db74">Tags: (unavailable) drwxrwxrwx 0:0 0 B ├── tmp
&lt;/span>&lt;span style="color:#e6db74">Id: 46176a0cbe9f3e95a08e3914ef9f4ac33fb1d412c9bacf2d1217616f76077fad.tar drwxr-xr-x 0:0 70 MB ├── usr
&lt;/span>&lt;span style="color:#e6db74">Digest: sha256:46176a0cbe9f3e95a08e3914ef9f4ac33fb1d412c9bacf2d1217616f76077fad drwxr-xr-x 0:0 21 MB │ ├─⊕ bin
&lt;/span>&lt;span style="color:#e6db74">Command: drwxr-xr-x 0:0 0 B │ ├── games
&lt;/span>&lt;span style="color:#e6db74">RUN /bin/sh -c mkdir -p &amp;#34;&lt;/span>$HTTPD_PREFIX&lt;span style="color:#e6db74">&amp;#34; &amp;amp;&amp;amp; chown www-data:www-data &amp;#34;&lt;/span>$HTTPD_PREFIX&lt;span style="color:#e6db74">&amp;#34; drwxr-xr-x 0:0 0 B │ ├── include
&lt;/span>&lt;span style="color:#e6db74"> # buildkit drwxr-xr-x 0:0 40 MB │ ├─⊕ lib
&lt;/span>&lt;span style="color:#e6db74"> drwxr-xr-x 0:0 0 B │ ├─⊕ lib64
&lt;/span>&lt;span style="color:#e6db74"> drwxr-xr-x 0:0 17 kB │ ├─⊕ libexec
&lt;/span>&lt;span style="color:#e6db74"> drwxr-xr-x 0:0 0 B │ ├── local
&lt;/span>&lt;span style="color:#e6db74"> drwxr-xr-x 33:33 0 B │ │ ├── apache2
&lt;/span>&lt;span style="color:#e6db74"> drwxr-xr-x 0:0 0 B │ │ ├── bin
&lt;/span>&lt;span style="color:#e6db74"> drwxr-xr-x 0:0 0 B │ │ ├── etc
&lt;/span>&lt;span style="color:#e6db74"> drwxr-xr-x 0:0 0 B │ │ ├── games
&lt;/span>&lt;span style="color:#e6db74">│ Image Details ├───────────────────────────────────────────────────────────────────── drwxr-xr-x 0:0 0 B │ │ ├── include
&lt;/span>&lt;span style="color:#e6db74"> drwxr-xr-x 0:0 0 B │ │ ├── lib
&lt;/span>&lt;span style="color:#e6db74">Image name: docker.io/library/httpd:latest -rwxrwxrwx 0:0 0 B │ │ ├── man → share/man
&lt;/span>&lt;span style="color:#e6db74">Total Image size: 147 MB drwxr-xr-x 0:0 0 B │ │ ├── sbin
&lt;/span>&lt;span style="color:#e6db74">Potential wasted space: 2.4 MB drwxr-xr-x 0:0 0 B │ │ ├─⊕ share
&lt;/span>&lt;span style="color:#e6db74">Image efficiency score: 99 % drwxr-xr-x 0:0 0 B │ │ └── src
&lt;/span>&lt;span style="color:#e6db74"> drwxr-xr-x 0:0 6.3 MB │ ├─⊕ sbin
&lt;/span>&lt;span style="color:#e6db74">Count Total Space Path drwxr-xr-x 0:0 3.2 MB │ ├─⊕ share
&lt;/span>&lt;span style="color:#e6db74"> 2 1.5 MB /var/cache/debconf/templates.dat drwxr-xr-x 0:0 0 B │ └── src
&lt;/span>&lt;span style="color:#e6db74"> 3 262 kB /var/lib/dpkg/status-old drwxr-xr-x 0:0 4.2 MB └─⊕ var
&lt;/span>&lt;span style="color:#e6db74"> 3 262 kB /var/lib/dpkg/status
&lt;/span>&lt;span style="color:#e6db74"> 2 109 kB /var/log/dpkg.log
&lt;/span>&lt;span style="color:#e6db74"> 2 82 kB /var/lib/dpkg/info/perl-base.list
&lt;/span>&lt;span style="color:#e6db74"> 2 43 kB /var/log/apt/term.log
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;code>dive&lt;/code> also calculates an &lt;em>efficiency score&lt;/em> by determining how many bytes of the final image (sum of all layers) are &amp;ldquo;wasted&amp;rdquo;.
An ideal score is 100%.
If a file is added in the first layer and then removed again in a following layer, this space is considered wasted and the efficiency score will be lower.
This can be used in &lt;a href="https://github.com/wagoodman/dive?tab=readme-ov-file#ci-integration">CI tests&lt;/a> to prevent needlessly big container images.&lt;/p>
&lt;div class="highlight">&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;">&lt;tr>&lt;td style="vertical-align:top;padding:0;margin:0;border:0;">
&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">22
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">23
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">24
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">25
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">26
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">27
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">28
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">29
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">30
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sh" data-lang="sh">$ CI&lt;span style="color:#f92672">=&lt;/span>true dive podman://docker.io/library/httpd:latest
Image Source: podman://docker.io/library/httpd:latest
Fetching image... &lt;span style="color:#f92672">(&lt;/span>this can take a &lt;span style="color:#66d9ef">while&lt;/span> &lt;span style="color:#66d9ef">for&lt;/span> large images&lt;span style="color:#f92672">)&lt;/span>
Analyzing image...
efficiency: 99.0433 %
wastedBytes: &lt;span style="color:#ae81ff">2399436&lt;/span> bytes &lt;span style="color:#f92672">(&lt;/span>2.4 MB&lt;span style="color:#f92672">)&lt;/span>
userWastedPercent: 3.3051 %
Inefficient Files:
Count Wasted Space File Path
&lt;span style="color:#ae81ff">2&lt;/span> 1.5 MB /var/cache/debconf/templates.dat
&lt;span style="color:#ae81ff">3&lt;/span> &lt;span style="color:#ae81ff">262&lt;/span> kB /var/lib/dpkg/status-old
&lt;span style="color:#ae81ff">3&lt;/span> &lt;span style="color:#ae81ff">262&lt;/span> kB /var/lib/dpkg/status
&lt;span style="color:#ae81ff">2&lt;/span> &lt;span style="color:#ae81ff">109&lt;/span> kB /var/log/dpkg.log
&lt;span style="color:#ae81ff">2&lt;/span> &lt;span style="color:#ae81ff">82&lt;/span> kB /var/lib/dpkg/info/perl-base.list
&lt;span style="color:#ae81ff">2&lt;/span> &lt;span style="color:#ae81ff">43&lt;/span> kB /var/log/apt/term.log
&lt;span style="color:#ae81ff">2&lt;/span> &lt;span style="color:#ae81ff">20&lt;/span> kB /var/cache/debconf/config.dat
&lt;span style="color:#ae81ff">3&lt;/span> &lt;span style="color:#ae81ff">20&lt;/span> kB /var/log/apt/eipp.log.xz
&lt;span style="color:#ae81ff">3&lt;/span> &lt;span style="color:#ae81ff">16&lt;/span> kB /etc/ld.so.cache
&lt;span style="color:#ae81ff">3&lt;/span> &lt;span style="color:#ae81ff">15&lt;/span> kB /var/lib/apt/extended_states
&lt;span style="color:#ae81ff">2&lt;/span> &lt;span style="color:#ae81ff">12&lt;/span> kB /var/cache/ldconfig/aux-cache
&lt;span style="color:#ae81ff">2&lt;/span> 9.6 kB /var/log/apt/history.log
&lt;span style="color:#ae81ff">2&lt;/span> 8.2 kB /var/cache/debconf/config.dat-old
&lt;span style="color:#ae81ff">3&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span> B /var/lib/dpkg/lock
&lt;span style="color:#ae81ff">2&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span> B /var/lib/dpkg/triggers/Unincorp
&lt;span style="color:#ae81ff">3&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span> B /var/lib/dpkg/triggers/Lock
Results:
PASS: highestUserWastedPercent
SKIP: highestWastedBytes: rule disabled
PASS: lowestEfficiency
Result:PASS &lt;span style="color:#f92672">[&lt;/span>Total:3&lt;span style="color:#f92672">]&lt;/span> &lt;span style="color:#f92672">[&lt;/span>Passed:2&lt;span style="color:#f92672">]&lt;/span> &lt;span style="color:#f92672">[&lt;/span>Failed:0&lt;span style="color:#f92672">]&lt;/span> &lt;span style="color:#f92672">[&lt;/span>Warn:0&lt;span style="color:#f92672">]&lt;/span> &lt;span style="color:#f92672">[&lt;/span>Skipped:1&lt;span style="color:#f92672">]&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>
&lt;h3 id="diffoci">
&lt;a href="#diffoci">#
&lt;/a>&amp;nbsp;diffoci
&lt;/h3>
&lt;p>The next tool serves a similar, yet slightly different purpose: &lt;a href="https://github.com/reproducible-containers/diffoci">diffoci&lt;/a> compares container images and shows the differences between them (unlike &lt;code>dive&lt;/code> which shows differences between layers).
It is the successor to the &lt;a href="https://github.com/GoogleContainerTools/container-diff/commit/b90c99c638e3ab0185d264c448ca22d349d93972">deprecated container-diff&lt;/a> tool.&lt;/p>
&lt;div class="highlight">&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;">&lt;tr>&lt;td style="vertical-align:top;padding:0;margin:0;border:0;">
&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sh" data-lang="sh">$ diffoci diff --semantic docker.io/library/httpd:alpine3.17 docker.io/library/httpd:alpine3.18
TYPE NAME INPUT-0 INPUT-1
File etc/alpine-release 44d3bbd769620a3aa2fd5403d0755f6a4afba3c14e55c156f1c88905866ff04e aac1e8712e84121ed6a270d8003e4b52d6cb474b7d1709cd80a4bc5b6c82aa6d
File lib/libssl.so.3 7c6e060a33d5e0969aced1645e669666b58f223f27d783b8e49471088e3f756a c751d77b54c8ec62103a7052bbf6efdd4f05fa0df1168153ca88e7a81d27d9a6
File bin/busybox 36d96947f81bee3a5e1d436a333a52209f051bb3556028352d4273a748e2d136 8c6864b97c2b9ff892c859c59363482cb19a546a33a204b83a24f29048b2118f
File etc/os-release e72f89989f15487206f906fe8fb12a6d4363273c0ec886e66e66222a301e42f6 a001686cc7651f44cbbeae86e783d42dc05dce05940c55f6e394b6f9bea4c631
File etc/ssl/certs/ca-certificates.crt 92dd040a840947f00a14f66e9e17a799051ad7f88ddcde851b3711ee0a78a7ac 824cefcee69de918c76b7b92776f304c3a4b7f6281539118bc1d41a9dd8476d9
Layer ctx:/manifests-0/layers-0/layer name &lt;span style="color:#e6db74">&amp;#34;lib/libapk.so.3.12.0&amp;#34;&lt;/span> only appears in input &lt;span style="color:#ae81ff">0&lt;/span>
File etc/issue c2dc1872792bfb7e7af7467b82cf136ad468acab74d99a97d0e479dbf4665dab 774e6ac5abc275013a07cba05be43f0953cf759f852d177aa25f27ff62ab2eb4
File etc/ssl/openssl.cnf.dist 15c6ec001241f54bed98c135f0dab42f4a5e489f22544613b0671198f8ad8318 f6045e326b439e8ee31d4efd020ddf660d616c67d03e0e8e7a927eb14cbb5d1f
Layer ctx:/manifests-0/layers-0/layer name &lt;span style="color:#e6db74">&amp;#34;etc/profile.d/locale.sh&amp;#34;&lt;/span> only appears in input &lt;span style="color:#ae81ff">0&lt;/span>
File lib/libz.so.1.2.13 a7df4375fc9f37d5c284ef74e1d782d0100ce3a907ad2cbc6287f769cb90aac4 e0df969fd057eeaeb3064663b0f0af0f776fa42c697b56726a3eec6b13ca6986
File lib/libcrypto.so.3 4b061badaa55a61bcb65a05445f84d3003e3d554c10a56a44d7e6f0c0e349e6e 169037db2377a8227ddba422ca6e03dfb61c6660a2594ecf3b306bc3323ff80c
File etc/apk/repositories e23f0c9897bd5f21f1451995f7e05470026012288d7ec811ed6e5567cd521c01 293ab007ea57d023c3418a8063966a40407ceb90517e60ad710772c70694f9c5
...
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>
&lt;h3 id="container-structure-test">
&lt;a href="#container-structure-test">#
&lt;/a>&amp;nbsp;container-structure-test
&lt;/h3>
&lt;p>If you&amp;rsquo;d like to make sure that the container images you&amp;rsquo;re building always contain certain configuration files, have dependencies installed etc., then &lt;a href="https://github.com/GoogleContainerTools/container-structure-test">container-structure-test&lt;/a> is the right tool.
Especially when you have to deal with a large number of (base) images and complex multi-stage builds, it is invaluable to run quick unit tests on them (after building) instead of having to go through a full integration test cycle (which usually involves uploading the container image to a registry, downloading it on the target host and then spinning up the application alongside all its dependencies).&lt;/p>
&lt;p>&lt;code>container-structure-test&lt;/code> takes a container image and a simple YAML configuration file as input:&lt;/p>
&lt;div class="highlight">&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;">&lt;tr>&lt;td style="vertical-align:top;padding:0;margin:0;border:0;">
&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="color:#f92672">schemaVersion&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;2.0.0&amp;#34;&lt;/span>
&lt;span style="color:#f92672">commandTests&lt;/span>:
- &lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#e6db74">&amp;#39;helm is installed&amp;#39;&lt;/span>
&lt;span style="color:#f92672">command&lt;/span>: &lt;span style="color:#e6db74">&amp;#39;helm&amp;#39;&lt;/span>
&lt;span style="color:#f92672">args&lt;/span>: [&lt;span style="color:#e6db74">&amp;#39;version&amp;#39;&lt;/span>]
&lt;span style="color:#f92672">exitCode&lt;/span>: &lt;span style="color:#ae81ff">0&lt;/span>
&lt;span style="color:#f92672">fileContentTests&lt;/span>:
- &lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#e6db74">&amp;#39;Velero is configured&amp;#39;&lt;/span>
&lt;span style="color:#f92672">path&lt;/span>: &lt;span style="color:#e6db74">&amp;#39;/root/.config/velero/config.json&amp;#39;&lt;/span>
&lt;span style="color:#f92672">expectedContents&lt;/span>:
- &lt;span style="color:#e6db74">&amp;#39;{&amp;#34;namespace&amp;#34;:&amp;#34;kube-system&amp;#34;}&amp;#39;&lt;/span>
&lt;span style="color:#f92672">fileExistenceTests&lt;/span>:
- &lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#e6db74">&amp;#39;kubectl bash completions are installed&amp;#39;&lt;/span>
&lt;span style="color:#f92672">path&lt;/span>: &lt;span style="color:#e6db74">&amp;#39;/etc/bash_completion.d/kubectl_completion&amp;#39;&lt;/span>
&lt;span style="color:#f92672">shouldExist&lt;/span>: &lt;span style="color:#66d9ef">true&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>and will then validate that all conditions are met:&lt;/p>
&lt;div class="highlight">&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;">&lt;tr>&lt;td style="vertical-align:top;padding:0;margin:0;border:0;">
&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">22
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sh" data-lang="sh">$ container-structure-test test --image &lt;span style="color:#e6db74">&amp;#34;registry.example.com/kube-tools&amp;#34;&lt;/span> --config container-structure-test.yaml
&lt;span style="color:#f92672">======================================================&lt;/span>
&lt;span style="color:#f92672">======&lt;/span> Test file: container-structure-test.yaml &lt;span style="color:#f92672">======&lt;/span>
&lt;span style="color:#f92672">======================================================&lt;/span>
&lt;span style="color:#f92672">===&lt;/span> RUN: Command Test: helm is installed
--- PASS
duration: 500.813594ms
stdout: version.BuildInfo&lt;span style="color:#f92672">{&lt;/span>Version:&lt;span style="color:#e6db74">&amp;#34;v3.11.2&amp;#34;&lt;/span>, GitCommit:&lt;span style="color:#e6db74">&amp;#34;912ebc1cd10d38d340f048efaf0abda047c3468e&amp;#34;&lt;/span>, GitTreeState:&lt;span style="color:#e6db74">&amp;#34;clean&amp;#34;&lt;/span>, GoVersion:&lt;span style="color:#e6db74">&amp;#34;go1.18.10&amp;#34;&lt;/span>&lt;span style="color:#f92672">}&lt;/span>
&lt;span style="color:#f92672">===&lt;/span> RUN: File Content Test: Velero is configured
--- PASS
duration: 0s
&lt;span style="color:#f92672">===&lt;/span> RUN: File Existence Test: kubectl bash completions are installed
--- PASS
duration: 0s
&lt;span style="color:#f92672">=======================================================&lt;/span>
&lt;span style="color:#f92672">=======================&lt;/span> RESULTS &lt;span style="color:#f92672">=======================&lt;/span>
&lt;span style="color:#f92672">=======================================================&lt;/span>
Passes: &lt;span style="color:#ae81ff">3&lt;/span>
Failures: &lt;span style="color:#ae81ff">0&lt;/span>
Duration: 0.519310751s
Total tests: &lt;span style="color:#ae81ff">3&lt;/span>
PASS
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Note that &lt;code>container-structure-test&lt;/code> works best with an actual Docker daemon, though with &lt;a href="https://github.com/GoogleContainerTools/container-structure-test/issues/225#issuecomment-971705933">some workarounds it is possible to use Podman&lt;/a>.&lt;/p>
&lt;p>I previously gave a lightning talk about this testing tool, you can watch the recording &lt;a href="https://cds.cern.ch/record/2792180">here&lt;/a>:&lt;/p>
&lt;iframe width="768" height="480" frameborder="0" src="https://cds.cern.ch/video/2792180?showTitle=true" allowfullscreen>&lt;/iframe>
&lt;h3 id="container-explorer">
&lt;a href="#container-explorer">#
&lt;/a>&amp;nbsp;container-explorer
&lt;/h3>
&lt;p>Given the disk image of a virtual (or physical) machine, &lt;a href="https://github.com/google/container-explorer">container-explorer&lt;/a> is a neat tool that allows you to explore the containers and container images on the host.
It supports containers run by &lt;code>containerd&lt;/code> as well as &lt;code>Docker&lt;/code>.
Since OpenShift uses the CRI-O container runtime, I haven&amp;rsquo;t used this tool myself but I imagine it can be quite helpful for post-mortem troubleshooting and forensic analysis.&lt;/p>
&lt;h3 id="skopeo">
&lt;a href="#skopeo">#
&lt;/a>&amp;nbsp;skopeo
&lt;/h3>
&lt;p>&lt;a href="https://github.com/containers/skopeo">skopeo&lt;/a> is a tool for working with container images in remote image registries.
It can show information about an image repository (list tags, digests and configuration) as well as copy/delete/sync images from one registry to another (without having to store the images locally).
This can be extremely handy when you are in an environment where you cannot run containers (e.g. inside a container!) or you don&amp;rsquo;t have root access.&lt;/p>
&lt;div class="highlight">&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;">&lt;tr>&lt;td style="vertical-align:top;padding:0;margin:0;border:0;">
&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">22
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">23
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">24
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">25
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">26
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">27
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">28
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">29
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">30
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">31
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">32
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">33
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">34
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">35
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">36
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">37
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">38
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">39
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">40
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">41
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">42
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">43
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">44
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">45
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">46
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">47
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">48
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">49
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">50
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">51
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">52
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">53
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">54
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">55
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">56
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">57
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">58
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">59
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">60
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">61
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">62
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">63
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">64
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">65
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">66
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">67
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">68
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">69
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">70
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">71
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">72
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">73
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">74
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">75
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">76
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">77
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sh" data-lang="sh">$ skopeo list-tags docker://docker.io/library/httpd
&lt;span style="color:#f92672">{&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;Repository&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;docker.io/library/httpd&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;Tags&amp;#34;&lt;/span>: &lt;span style="color:#f92672">[&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;2&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;2-alpine&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;2-alpine3.13&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;2-alpine3.14&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;2-alpine3.15&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;2-alpine3.16&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;2-alpine3.17&amp;#34;&lt;/span>,
...
$ skopeo inspect docker://docker.io/library/httpd:latest
&lt;span style="color:#f92672">{&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;Name&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;docker.io/library/httpd&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;Digest&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;sha256:36c8c79f900108f0f09fd4148ad35ade57cba0dc19d13f3d15be24ce94e6a639&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;RepoTags&amp;#34;&lt;/span>: &lt;span style="color:#f92672">[&lt;/span> ... &lt;span style="color:#f92672">]&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;Created&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;2024-04-05T21:49:16Z&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;DockerVersion&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;Labels&amp;#34;&lt;/span>: null,
&lt;span style="color:#e6db74">&amp;#34;Architecture&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;amd64&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;Os&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;linux&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;Layers&amp;#34;&lt;/span>: &lt;span style="color:#f92672">[&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;sha256:b0a0cf830b12453b7e15359a804215a7bcccd3788e2bcecff2a03af64bbd4df7&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;sha256:851c52adaa9bf680b2eaa45164baa37665418fb02666fb36c268002edd853994&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;sha256:39d9f60535a61833df2e57cc08221031d3ae50f3955a6d6b0153214619d357fb&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;sha256:943a2b3cf551375517593790b58407ffc7028b4b34bca6c0756b76708ea4b3ce&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;sha256:ea83e81966d64f34a57ffcc118b75ad19bc9321f9809cf9b0df25548a2fa695e&amp;#34;&lt;/span>
&lt;span style="color:#f92672">]&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;LayersData&amp;#34;&lt;/span>: &lt;span style="color:#f92672">[&lt;/span>
&lt;span style="color:#f92672">{&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;MIMEType&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;application/vnd.oci.image.layer.v1.tar+gzip&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;Digest&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;sha256:b0a0cf830b12453b7e15359a804215a7bcccd3788e2bcecff2a03af64bbd4df7&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;Size&amp;#34;&lt;/span>: 29150479,
&lt;span style="color:#e6db74">&amp;#34;Annotations&amp;#34;&lt;/span>: null
&lt;span style="color:#f92672">}&lt;/span>,
&lt;span style="color:#f92672">{&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;MIMEType&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;application/vnd.oci.image.layer.v1.tar+gzip&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;Digest&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;sha256:851c52adaa9bf680b2eaa45164baa37665418fb02666fb36c268002edd853994&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;Size&amp;#34;&lt;/span>: 146,
&lt;span style="color:#e6db74">&amp;#34;Annotations&amp;#34;&lt;/span>: null
&lt;span style="color:#f92672">}&lt;/span>,
&lt;span style="color:#f92672">{&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;MIMEType&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;application/vnd.oci.image.layer.v1.tar+gzip&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;Digest&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;Size&amp;#34;&lt;/span>: 32,
&lt;span style="color:#e6db74">&amp;#34;Annotations&amp;#34;&lt;/span>: null
&lt;span style="color:#f92672">}&lt;/span>,
&lt;span style="color:#f92672">{&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;MIMEType&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;application/vnd.oci.image.layer.v1.tar+gzip&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;Digest&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;sha256:39d9f60535a61833df2e57cc08221031d3ae50f3955a6d6b0153214619d357fb&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;Size&amp;#34;&lt;/span>: 4006988,
&lt;span style="color:#e6db74">&amp;#34;Annotations&amp;#34;&lt;/span>: null
&lt;span style="color:#f92672">}&lt;/span>,
&lt;span style="color:#f92672">{&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;MIMEType&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;application/vnd.oci.image.layer.v1.tar+gzip&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;Digest&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;sha256:943a2b3cf551375517593790b58407ffc7028b4b34bca6c0756b76708ea4b3ce&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;Size&amp;#34;&lt;/span>: 26027444,
&lt;span style="color:#e6db74">&amp;#34;Annotations&amp;#34;&lt;/span>: null
&lt;span style="color:#f92672">}&lt;/span>,
&lt;span style="color:#f92672">{&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;MIMEType&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;application/vnd.oci.image.layer.v1.tar+gzip&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;Digest&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;sha256:ea83e81966d64f34a57ffcc118b75ad19bc9321f9809cf9b0df25548a2fa695e&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;Size&amp;#34;&lt;/span>: 293,
&lt;span style="color:#e6db74">&amp;#34;Annotations&amp;#34;&lt;/span>: null
&lt;span style="color:#f92672">}&lt;/span>
&lt;span style="color:#f92672">]&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;Env&amp;#34;&lt;/span>: &lt;span style="color:#f92672">[&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;PATH=/usr/local/apache2/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;HTTPD_PREFIX=/usr/local/apache2&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;HTTPD_VERSION=2.4.59&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;HTTPD_SHA256=ec51501ec480284ff52f637258135d333230a7d229c3afa6f6c2f9040e321323&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;HTTPD_PATCHES=&amp;#34;&lt;/span>
&lt;span style="color:#f92672">]&lt;/span>
&lt;span style="color:#f92672">}&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>
&lt;h3 id="crane">
&lt;a href="#crane">#
&lt;/a>&amp;nbsp;crane
&lt;/h3>
&lt;p>The use case for &lt;a href="https://github.com/google/go-containerregistry/blob/main/cmd/crane/doc/crane.md">crane&lt;/a> is very similar to &lt;code>skopeo&lt;/code>, but it goes a step further: &lt;code>crane&lt;/code> can also modify existing container images.
Adding or changing layers, flattening (&amp;ldquo;squashing&amp;rdquo;) images, modifying metadata (environment variables, entrypoint, labels etc.).
It does this all directly in the registry, meaning no local container runtime is needed.&lt;/p>
&lt;div class="highlight">&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;">&lt;tr>&lt;td style="vertical-align:top;padding:0;margin:0;border:0;">
&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">22
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">23
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">24
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">25
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">26
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">27
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">28
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">29
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">30
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">31
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">32
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">33
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">34
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">35
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">36
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">37
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">38
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">39
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">40
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">41
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">42
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">43
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">44
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">45
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">46
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">47
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">48
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">49
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">50
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">51
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">52
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">53
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">54
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sh" data-lang="sh">&lt;span style="color:#75715e"># list files in an image&lt;/span>
$ crane export docker.io/library/httpd:latest - | tar -tvf - | head
drwxr-xr-x 0/0 &lt;span style="color:#ae81ff">0&lt;/span> 2024-04-23 17:00 usr
drwxr-xr-x 0/0 &lt;span style="color:#ae81ff">0&lt;/span> 2024-04-24 06:54 usr/local
drwxr-xr-x 0/0 &lt;span style="color:#ae81ff">0&lt;/span> 2024-04-24 06:57 usr/local/bin
-rwxr-xr-x 0/0 &lt;span style="color:#ae81ff">138&lt;/span> 2024-04-24 06:54 usr/local/bin/httpd-foreground
drwxr-xr-x 0/0 &lt;span style="color:#ae81ff">0&lt;/span> 2024-04-24 06:57 etc
drwxr-xr-x 0/0 &lt;span style="color:#ae81ff">0&lt;/span> 2024-04-24 06:54 etc/gss
drwxr-xr-x 0/0 &lt;span style="color:#ae81ff">0&lt;/span> 2023-08-14 22:06 etc/gss/mech.d
-rw-r--r-- 0/0 &lt;span style="color:#ae81ff">6682&lt;/span> 2024-04-24 06:57 etc/ld.so.cache
drwxr-xr-x 0/0 &lt;span style="color:#ae81ff">0&lt;/span> 2024-04-24 06:57 usr/lib
drwxr-xr-x 0/0 &lt;span style="color:#ae81ff">0&lt;/span> 2024-04-24 06:57 usr/lib/x86_64-linux-gnu
&lt;span style="color:#75715e"># squash an image into a single layer and push it to a different registry&lt;/span>
$ crane flatten docker.io/library/httpd:latest --tag registry.example.com/jack/httpd:flat --platform linux/amd64
...
&lt;span style="color:#75715e"># check that the new image only has one layer&lt;/span>
$ crane config registry.example.com/jack/httpd:flat | jq .
&lt;span style="color:#f92672">{&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;architecture&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;amd64&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;created&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;2024-04-05T21:49:16Z&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;history&amp;#34;&lt;/span>: &lt;span style="color:#f92672">[&lt;/span>
&lt;span style="color:#f92672">{&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;created&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;0001-01-01T00:00:00Z&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;created_by&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;crane flatten sha256:518e9447a236de47cc2fb4f2dbf06466b6cd5cf50f9951742f9a20af76e8118d&amp;#34;&lt;/span>
&lt;span style="color:#f92672">}&lt;/span>
&lt;span style="color:#f92672">]&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;os&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;linux&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;rootfs&amp;#34;&lt;/span>: &lt;span style="color:#f92672">{&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;type&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;layers&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;diff_ids&amp;#34;&lt;/span>: &lt;span style="color:#f92672">[&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;sha256:3da7dd597070d0a53bef421a06dc2b7e3e6e937449c6f78e144ed4095c07a52a&amp;#34;&lt;/span>
&lt;span style="color:#f92672">]&lt;/span>
&lt;span style="color:#f92672">}&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;config&amp;#34;&lt;/span>: &lt;span style="color:#f92672">{&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;Cmd&amp;#34;&lt;/span>: &lt;span style="color:#f92672">[&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;httpd-foreground&amp;#34;&lt;/span>
&lt;span style="color:#f92672">]&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;Env&amp;#34;&lt;/span>: &lt;span style="color:#f92672">[&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;PATH=/usr/local/apache2/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;HTTPD_PREFIX=/usr/local/apache2&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;HTTPD_VERSION=2.4.59&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;HTTPD_SHA256=ec51501ec480284ff52f637258135d333230a7d229c3afa6f6c2f9040e321323&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;HTTPD_PATCHES=&amp;#34;&lt;/span>
&lt;span style="color:#f92672">]&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;WorkingDir&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;/usr/local/apache2&amp;#34;&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;ExposedPorts&amp;#34;&lt;/span>: &lt;span style="color:#f92672">{&lt;/span>
&lt;span style="color:#e6db74">&amp;#34;80/tcp&amp;#34;&lt;/span>: &lt;span style="color:#f92672">{}&lt;/span>
&lt;span style="color:#f92672">}&lt;/span>,
&lt;span style="color:#e6db74">&amp;#34;ArgsEscaped&amp;#34;&lt;/span>: true,
&lt;span style="color:#e6db74">&amp;#34;StopSignal&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;SIGWINCH&amp;#34;&lt;/span>
&lt;span style="color:#f92672">}&lt;/span>
&lt;span style="color:#f92672">}&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Check out their &lt;a href="https://github.com/google/go-containerregistry/blob/main/cmd/crane/recipes.md">recipes page&lt;/a> for some more examples and take a look at the &lt;a href="https://github.com/google/go-containerregistry">go-containerregistry library&lt;/a> (which exposes the primitives &lt;code>crane&lt;/code> is built on through a Go API) as well.&lt;/p>
&lt;h3 id="dredge">
&lt;a href="#dredge">#
&lt;/a>&amp;nbsp;dredge
&lt;/h3>
&lt;p>The final item in the toolbox is &lt;a href="https://github.com/mthalman/dredge">dredge&lt;/a>.
Much like &lt;code>skopeo&lt;/code> and &lt;code>crane&lt;/code> it allows you to inspect repositories and images from remote registries.
One particularly neat feature is the diffing capability: it can show differences in files between two images.&lt;/p>
&lt;div class="highlight">&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;">&lt;tr>&lt;td style="vertical-align:top;padding:0;margin:0;border:0;">
&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">22
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">23
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">24
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">25
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">26
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">27
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">28
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">29
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">30
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">31
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">32
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">33
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">34
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">35
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">36
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">37
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">38
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">39
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">40
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">41
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">42
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">43
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">44
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">45
&lt;/span>&lt;span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">46
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sh" data-lang="sh">$ dredge image compare layers httpd:2.2 httpd:2.4 --os linux --arch amd64 --output&lt;span style="color:#f92672">=&lt;/span>inline --compressed-size
- sha256:f49cf87b52c10aa83b4f4405800527a74400fb19ea1821d209293bc4d53966aa
- Size &lt;span style="color:#f92672">(&lt;/span>compressed&lt;span style="color:#f92672">)&lt;/span>: 50.2 MB
+ sha256:b0a0cf830b12453b7e15359a804215a7bcccd3788e2bcecff2a03af64bbd4df7
+ Size &lt;span style="color:#f92672">(&lt;/span>compressed&lt;span style="color:#f92672">)&lt;/span>: 27.8 MB
- sha256:24b1e09cbcb7a380a9c98956c6131125b3e0f0a7965d24db460f3548bf300eae
- Size &lt;span style="color:#f92672">(&lt;/span>compressed&lt;span style="color:#f92672">)&lt;/span>: &lt;span style="color:#ae81ff">155&lt;/span> bytes
+ sha256:851c52adaa9bf680b2eaa45164baa37665418fb02666fb36c268002edd853994
+ Size &lt;span style="color:#f92672">(&lt;/span>compressed&lt;span style="color:#f92672">)&lt;/span>: &lt;span style="color:#ae81ff">146&lt;/span> bytes
- sha256:8a4e0d64e915177206a8c2729a60e6b5001ae5bf47d598ad79a626e5cf983309
- Size &lt;span style="color:#f92672">(&lt;/span>compressed&lt;span style="color:#f92672">)&lt;/span>: 11.4 MB
+ sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1
+ Size &lt;span style="color:#f92672">(&lt;/span>compressed&lt;span style="color:#f92672">)&lt;/span>: &lt;span style="color:#ae81ff">32&lt;/span> bytes
- sha256:bcbe0eb4ca5196217c6368138d5e1feabdb83272dc52859a6e5f2e81aec0c939
- Size &lt;span style="color:#f92672">(&lt;/span>compressed&lt;span style="color:#f92672">)&lt;/span>: 1.9 MB
+ sha256:39d9f60535a61833df2e57cc08221031d3ae50f3955a6d6b0153214619d357fb
+ Size &lt;span style="color:#f92672">(&lt;/span>compressed&lt;span style="color:#f92672">)&lt;/span>: 3.8 MB
- sha256:16e370c15d382f71f43248107f9524085de33a42809f33034e4571e503f358bf
- Size &lt;span style="color:#f92672">(&lt;/span>compressed&lt;span style="color:#f92672">)&lt;/span>: &lt;span style="color:#ae81ff">304&lt;/span> bytes
+ sha256:943a2b3cf551375517593790b58407ffc7028b4b34bca6c0756b76708ea4b3ce
+ Size &lt;span style="color:#f92672">(&lt;/span>compressed&lt;span style="color:#f92672">)&lt;/span>: 24.8 MB
+ sha256:ea83e81966d64f34a57ffcc118b75ad19bc9321f9809cf9b0df25548a2fa695e
+ Size &lt;span style="color:#f92672">(&lt;/span>compressed&lt;span style="color:#f92672">)&lt;/span>: &lt;span style="color:#ae81ff">293&lt;/span> bytes
$ dredge image compare files httpd:2.2 httpd:2.4 --os linux --arch amd64 --base-layer-index &lt;span style="color:#ae81ff">4&lt;/span> --target-layer-index &lt;span style="color:#ae81ff">4&lt;/span>
...
$ dredge image save-layers httpd:2.2 /tmp/httpd-2.2 --layer-index &lt;span style="color:#ae81ff">4&lt;/span> --arch amd64 --os linux --no-squash
Getting layers &lt;span style="color:#66d9ef">for&lt;/span> httpd:2.2
Layer sha256:16e370c15d382f71f43248107f9524085de33a42809f33034e4571e503f358bf
Downloading layer...
Extracting layer...
$ tree /tmp/httpd-2.2
/tmp/httpd-2.2
└── layer4-16e370c15d382f71f43248107f9524085de33a42809f33034e4571e503f358bf
└── usr
└── local
└── bin
└── httpd-foreground
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>It&amp;rsquo;s also notable that &lt;code>dredge&lt;/code> is written in C# with the .NET framework (unlike all other tools which are written in Go).&lt;/p>
&lt;hr>
&lt;p>That&amp;rsquo;s all for today! I hope you found some new tools for your toolbox.
Some of them have overlapping functionality, so you can pick and choose the appropriate tool for the task at hand.
Also make sure to check out the &lt;a href="https://github.com/veggiemonk/awesome-docker">awesome-docker&lt;/a> and &lt;a href="https://github.com/Friz-zy/awesome-linux-containers">awesome-linux-containers&lt;/a> lists.&lt;/p></description></item></channel></rss>