{"id":489894,"date":"2022-09-03T03:48:04","date_gmt":"2022-09-03T00:48:04","guid":{"rendered":"https:\/\/en.buradabiliyorum.com\/what-are-docker-image-layers\/"},"modified":"2022-09-03T03:48:04","modified_gmt":"2022-09-03T00:48:04","slug":"what-are-docker-image-layers","status":"publish","type":"post","link":"https:\/\/buradabiliyorum.com\/en\/what-are-docker-image-layers\/","title":{"rendered":"#What Are Docker Image Layers?"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_85 counter-hierarchy ez-toc-counter ez-toc-custom ez-toc-container-direction\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<label for=\"ez-toc-cssicon-toggle-item-6a3fab074a9d1\" class=\"ez-toc-cssicon-toggle-label\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #dd3333;color:#dd3333\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #dd3333;color:#dd3333\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/label><input type=\"checkbox\"  id=\"ez-toc-cssicon-toggle-item-6a3fab074a9d1\" checked aria-label=\"Toggle\" \/><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/buradabiliyorum.com\/en\/what-are-docker-image-layers\/#%E2%80%9CWhat_Are_Docker_Image_Layers%E2%80%9D\" >&#8220;What Are Docker Image Layers?&#8221;<\/a><ul class='ez-toc-list-level-2' ><li class='ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/buradabiliyorum.com\/en\/what-are-docker-image-layers\/#Whats_an_Image\" >What\u2019s an Image?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/buradabiliyorum.com\/en\/what-are-docker-image-layers\/#What_are_Layers\" >What are Layers?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/buradabiliyorum.com\/en\/what-are-docker-image-layers\/#The_Role_of_Layers\" >The Role of Layers<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/buradabiliyorum.com\/en\/what-are-docker-image-layers\/#Layers_and_Pull_Operations\" >Layers and Pull Operations<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/buradabiliyorum.com\/en\/what-are-docker-image-layers\/#Inspecting_Image_Layers\" >Inspecting Image Layers<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/buradabiliyorum.com\/en\/what-are-docker-image-layers\/#Summary\" >Summary<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n<h1><span class=\"ez-toc-section\" id=\"%E2%80%9CWhat_Are_Docker_Image_Layers%E2%80%9D\"><\/span>&#8220;What Are Docker Image Layers?&#8221;<span class=\"ez-toc-section-end\"><\/span><\/h1>\n<div>\n<img loading=\"lazy\" decoding=\"async\" class=\"type:primaryImage alignnone size-full wp-image-805981\" data-pagespeed-no-defer=\"\" src=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2022\/05\/Docker-New.jpeg?width=1198&amp;trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"Graphic showing the Docker logo\" width=\"1600\" height=\"900\"\/><\/p>\n<p>Docker images consist of multiple layers that collectively provide the content you see in your containers. But what actually is a layer, and how does it differ from a complete image?<\/p>\n<p>In this article you\u2019ll learn how to distinguish these two concepts and why the difference matters. While you can use Docker without a thorough understanding of layers, having an awareness of their purpose will help you identify optimization opportunities.<\/p>\n<h2 id=\"whats-an-image\"><span class=\"ez-toc-section\" id=\"Whats_an_Image\"><\/span>What\u2019s an Image?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>A Docker \u201cimage\u201d behaves like a template from which consistent containers can be created. If Docker was a traditional virtual machine, the image could be likened to the ISO used to install your VM. This isn\u2019t a robust comparison, as Docker differs from VMs in terms of both concept and implementation, but it\u2019s a useful starting point nonetheless.<\/p>\n<p>Images define the initial filesystem state of new containers. They bundle your <a href=\"https:\/\/buradabiliyorum.com\/en\/category\/download-scripts-themes-apps\/\" data-internallinksmanager029f6b8e52c=\"9\" title=\"Download Scripts &amp; Themes &amp; Apps\" target=\"_blank\" rel=\"noopener\">app<\/a>lication\u2019s source code and its dependencies into a self-contained package that\u2019s ready to use with a container runtime. Within the image, filesystem content is represented as multiple independent layers.<\/p>\n<h2 id=\"what-are-layers\"><span class=\"ez-toc-section\" id=\"What_are_Layers\"><\/span>What are Layers?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Layers are a result of the way Docker images are built. Each step in a Dockerfile creates a new \u201clayer\u201d that\u2019s essentially a diff of the filesystem changes since the last step. Metadata instructions such as <code>LABEL<\/code> and <code>MAINTAINER<\/code> do not create layers because they don\u2019t affect the filesystem.<\/p>\n<p>This image has two instructions (<code>COPY <\/code>and <code>RUN<\/code>) so it\u2019ll create two layers:<\/p>\n<pre><code>FROM ubuntu:latest&#13;\nCOPY foo.txt \/foo.txt&#13;\nRUN date &gt; \/built-on.txt<\/code><\/pre>\n<ul>\n<li>The first step copies <code>foo.txt<\/code> into a new layer that\u2019s based on the <code>ubuntu:latest<\/code> image.<\/li>\n<li>The second step runs the <code>date<\/code> command and pipes its output into a file. This creates a second layer that\u2019s based on the previous one.<\/li>\n<\/ul>\n<p>Create <code>foo.txt<\/code> in your working directory:<\/p>\n<pre><code>$ echo \"Hello World\" &gt; foo.txt<\/code><\/pre>\n<p>Now build the sample image:<\/p>\n<pre><code>$ docker build . -t demo:latest&#13;\nSending build context to Docker daemon   2.56kB&#13;\nStep 1\/3 : FROM ubuntu:latest&#13;\n ---&gt; df5de72bdb3b&#13;\nStep 2\/3 : COPY foo.txt \/foo.txt&#13;\n ---&gt; 4932aede6a15&#13;\nStep 3\/3 : RUN date &gt; \/built-on.txt&#13;\n ---&gt; Running in 91d260fc2e68&#13;\nRemoving inter<a href=\"https:\/\/buradabiliyorum.com\/en\/category\/social-mediaa\/\" data-internallinksmanager029f6b8e52c=\"1\" title=\"Social Media\" target=\"_blank\" rel=\"noopener\">media<\/a>te container 91d260fc2e68&#13;\n ---&gt; 6f653c6a60fa&#13;\nSuccessfully built 6f653c6a60fa&#13;\nSuccessfully tagged foo:latest<\/code><\/pre>\n<p>Each build step emits the ID of the created layer. The last step\u2019s layer becomes the final image so it gets tagged with <code>foo:latest<\/code>.<\/p>\n<p>The sequence reveals that <strong>layers are valid Docker images<\/strong>. Although the term \u201clayer\u201d isn\u2019t normally used to refer to a tagged image, all tagged images are technically just layers with an identifier assigned.<\/p>\n<p>You can start a container from an intermediate layer\u2019s image:<\/p>\n<pre><code>$ docker run -it 4932aede6a15 sh&#13;\n# cat \/foo.txt&#13;\nHello World&#13;\n# cat \/built-on.txt&#13;\ncat: \/built-on.txt: No such file or directory<\/code><\/pre>\n<p>This example starts a container from the layer created by the second build step. <code>foo.txt<\/code> is available in the container but <code>built-on.txt<\/code> doesn\u2019t exist because it\u2019s not added until the third step. That file\u2019s only available in the filesystems of subsequent layers.<\/p>\n<h2 id=\"the-role-of-layers\"><span class=\"ez-toc-section\" id=\"The_Role_of_Layers\"><\/span>The Role of Layers<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Layers contain the changes created by a build step, relative to the previous layer in the Dockerfile. <code>FROM<\/code> instructions are a special case that reference the final layer of an existing image.<\/p>\n<p>Layers allow build steps to be cached to avoid redundant work. Docker can skip unchanged instructions in your Dockerfile by reusing the previously created layer. It bases the next step on that existing layer, instead of building a new one.<\/p>\n<p>You can see this by modifying your Dockerfile as follows:<\/p>\n<pre><code>FROM ubuntu:latest&#13;\nCOPY foo.txt \/foo.txt&#13;\nRUN date +%Y-%m-%d &gt; \/built-on.txt<\/code><\/pre>\n<p>The third build step has changed. Now rebuild your image:<\/p>\n<pre><code>$ docker build . -t demo:latest&#13;\nSending build context to Docker daemon  3.584kB&#13;\nStep 1\/3 : FROM ubuntu:latest&#13;\n ---&gt; df5de72bdb3b&#13;\nStep 2\/3 : COPY foo.txt \/foo.txt&#13;\n ---&gt; Using cache&#13;\n ---&gt; 4932aede6a15&#13;\nStep 3\/3 : RUN date +%Y-%m-%d &gt; \/built-on.txt&#13;\n ---&gt; Running in 2b91ec0462c4&#13;\nRemoving intermediate container 2b91ec0462c4&#13;\n ---&gt; c6647ff378c1&#13;\nSuccessfully built c6647ff378c1&#13;\nSuccessfully tagged demo:latest<\/code><\/pre>\n<p>The second build step shows as <code>Using cache<\/code> and produces the same layer ID. Docker could skip building this layer as it was already created earlier and <code>foo.txt<\/code> hasn\u2019t changed since the first build.<\/p>\n<p>This caching only works up to the point a layer is modified. All the steps after that layer will need to be rebuilt too so they\u2019re based on the new filesystem revision.<\/p>\n<h2 id=\"layers-and-pull-operations\"><span class=\"ez-toc-section\" id=\"Layers_and_Pull_Operations\"><\/span>Layers and Pull Operations<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Another benefit of layers is how they enable partial image pulls. Once you\u2019ve downloaded a few images to your machine, you\u2019ll often find new pulls can skip some layers that you already have. This image contains 13 layers but only six had to be downloaded by the pull operation:<\/p>\n<pre><code>docker pull php:8.0-apache&#13;\n8.0-apache: Pulling from library\/php&#13;\n7a6db449b51b: Already exists &#13;\nad2afdb99a9d: Already exists &#13;\ndbc5aa907229: Already exists &#13;\n82f252ab4ad1: Already exists &#13;\nbf5b34fc9894: Already exists &#13;\n6161651d3d95: Already exists &#13;\ncf2adf296ef1: Already exists &#13;\nf0d7c5221e44: Pull complete &#13;\nf647198f6316: Pull complete &#13;\nc37afe1da4e5: Pull complete &#13;\n09c93531cbca: Pull complete &#13;\nfef371007dd3: Pull complete &#13;\n52043dbb1c06: Pull complete &#13;\nDigest: sha256:429889e8f9eac0a806a005b0728a004303b0d49d77b09496d39158707abd6280&#13;\nStatus: Downloaded newer image for php:8.0-apache&#13;\ndocker.io\/library\/php:8.0-apache<\/code><\/pre>\n<p>The other layers were already present on the Docker host so they could be reused. This improves performance and avoids wasting network bandwidth.<\/p>\n<h2 id=\"inspecting-image-layers\"><span class=\"ez-toc-section\" id=\"Inspecting_Image_Layers\"><\/span>Inspecting Image Layers<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>You can list the layers within an image by running the <code>docker image history<\/code> command. Each layer displays the ID of the created image and the Dockerfile instruction that caused the change. You can see the total size of the content within the layer too.<\/p>\n<pre><code>$ docker image history &#13;\nIMAGE          CREATED         CREATED BY                                      SIZE      COMMENT&#13;\n6f653c6a60fa   4 minutes ago   \/bin\/sh -c date &gt; \/built-on.txt                 29B       &#13;\nf8420d1a96f3   4 minutes ago   \/bin\/sh -c #(nop) COPY file:a5630a7506b26a37...   0B        &#13;\ndf5de72bdb3b   4 weeks ago     \/bin\/sh -c #(nop)  CMD [\"bash\"]                 0B        &#13;\n&lt;missing&gt;      4 weeks ago     \/bin\/sh -c #(nop) ADD file:396eeb65c8d737180...   77.8MB    <\/code><\/pre>\n<p>The last layer displays as <code>&lt;missing&gt;<\/code> because it refers to a layer within the <code>ubuntu:latest<\/code> base image. This is not available locally, as only the final layer of the base image (<code>df5de72bdb3b<\/code>) gets pulled down during builds. There\u2019s no need to independently pull all the intermediate layers when you want to use a specific image.<\/p>\n<h2 id=\"summary\"><span class=\"ez-toc-section\" id=\"Summary\"><\/span>Summary<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Docker images and layers are <a href=\"https:\/\/buradabiliyorum.com\/en\/category\/general\/\" data-internallinksmanager029f6b8e52c=\"3\" title=\"General\" target=\"_blank\" rel=\"noopener\">general<\/a>ly interchangeable terms. A layer is an image and an image is formed from one or more layers. The major difference lies in tags: an image will be tagged and designed for end users, while the term \u201clayer\u201d normally refers to the untagged intermediate images created as part of a build operation. These aren\u2019t visible unless you go looking for them.<\/p>\n<p>There\u2019s one more topic that relates to layers: running containers add an extra <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/docs.docker.com\/storage\/storagedriver\/#images-and-layers\">writable layer<\/a> on top of their image. Layers sourced from the container\u2019s image are read-only so filesystem modifications made by the container target its ephemeral writable layer. The writable layer gets discarded when the container\u2019s stopped or deleted.<\/p>\n<\/div>\n<p><script>\n setTimeout(function(){\n  !function(f,b,e,v,n,t,s)\n  {if(f.fbq)return;n=f.fbq=function(){n.callMethod?\n  n.callMethod.apply(n,arguments):n.queue.push(arguments)};\n  if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';\n  n.queue=[];t=b.createElement(e);t.async=!0;\n  t.src=v;s=b.getElementsByTagName(e)[0];\n  s.parentNode.insertBefore(t,s) } (window, document,'script',\n  'https:\/\/connect.facebook.net\/en_US\/fbevents.js');\n   fbq('init', '335401813750447');\n   fbq('track', 'PageView');\n  },3000);\n<\/script><\/p>\n<blockquote><p><strong><span style=\"color: #ff6600;\">If you liked the article, do not forget to share it with your friends. Follow us on\u00a0<span style=\"color: #ff0000;\"><a style=\"color: #ff0000;\" href=\"https:\/\/news.google.com\/publications\/CAAqBwgKMLG0nwswvr63Aw\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Google News<\/a><\/span>\u00a0too, click on the star and choose us from your favorites.<\/span><\/strong><\/p><\/blockquote>\n<blockquote>\n<p style=\"text-align: center;\">For forums sites go to <span style=\"color: #ff9900;\"><a style=\"color: #ff9900;\" href=\"https:\/\/forum.buradabiliyorum.com\/\" target=\"_blank\" rel=\"noopener\">Forum.BuradaBiliyorum.Com<\/a><\/span><\/strong><\/p>\n<\/blockquote>\n<blockquote>\n<p style=\"text-align: center;\"><strong>If you want to read more like this article, you can visit our <span style=\"color: #ff9900;\"><a style=\"color: #ff9900;\" href=\"https:\/\/en.buradabiliyorum.com\/technology\/\" target=\"_blank\" rel=\"noopener\">Technology category.<\/a><\/span><\/strong><\/p>\n<\/blockquote>\n<p><span style=\"color: black;\"><a style=\"color: #ff9900;\" href=\"https:\/\/www.howtogeek.com\/devops\/what-are-docker-image-layers\/\" target=\"_blank\" rel=\"noopener\">Source<\/a><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8220;What Are Docker Image Layers?&#8221; Docker images consist of multiple layers that collectively provide the content you see in your containers. But what actually is a layer, and how does it differ from a complete image? In this article you\u2019ll learn how to distinguish these two concepts and why the difference matters. While you can&#8230;<\/p>\n","protected":false},"author":1,"featured_media":489895,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"fifu_image_url":"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2022\/05\/Docker-New.jpeg?height=200p&trim=2,2,2,2","fifu_image_alt":"","footnotes":""},"categories":[18],"tags":[],"class_list":["post-489894","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-technology"],"_links":{"self":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/489894","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/comments?post=489894"}],"version-history":[{"count":0,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/489894\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media\/489895"}],"wp:attachment":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media?parent=489894"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/categories?post=489894"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/tags?post=489894"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}