{"id":566,"date":"2014-09-13T23:56:05","date_gmt":"2014-09-14T05:56:05","guid":{"rendered":"http:\/\/www.crccheck.com\/blog\/?p=566"},"modified":"2015-10-11T22:22:11","modified_gmt":"2015-10-12T04:22:11","slug":"optimizing-docker-image-size-for-real","status":"publish","type":"post","link":"https:\/\/www.crccheck.com\/blog\/optimizing-docker-image-size-for-real\/","title":{"rendered":"Optimizing Docker Image Size For Real"},"content":{"rendered":"<p>I&#8217;ve come across tips on how to keep Docker images small and Dockerfiles with strange lines that seem to exist only to optimize image size. Well, it turns out they&#8217;re all wrong.<\/p>\n<p>They may have an effect with flat Docker images, but everything else (i.e. 99% of what people do), cleanup steps are just extra steps. When Docker builds an image from a Dockerfile, every step is a checkpoint, and every step is saved. If you add 100 MB in one step, then delete it the next, that 100 MB still needs to be saved so other Dockerfiles with the same step can reuse it.<\/p>\n<h2>Results<\/h2>\n<pre><code>REPOSITORY               TAG             IMAGE ID            CREATED             VIRTUAL SIZE\r\n<a title=\"One command per line\" href=\"https:\/\/github.com\/crccheck\/docker-pod\/blob\/master\/xxx\/Dockerfile.baseline\" target=\"_blank\">test\/baseline<\/a>            latest          7b590dec9b43        7 hours ago         272.6 MB\r\n<a title=\"One command per line, lots of extra lines\" href=\"https:\/\/github.com\/crccheck\/docker-pod\/blob\/master\/xxx\/Dockerfile.baseline_lines\" target=\"_blank\">test\/baseline_lines<\/a>      latest          e165025980f7        9 minutes ago       272.6 MB\r\n<a title=\"Extra checkpoint that deletes apt\/lists\" href=\"https:\/\/github.com\/crccheck\/docker-pod\/blob\/master\/xxx\/Dockerfile.baseline_lists\" target=\"_blank\">test\/baseline_lists<\/a>      latest          b40f9e108a93        About an hour ago   272.6 MB\r\n<a title=\"Cram installation into one line\" href=\"https:\/\/github.com\/crccheck\/docker-pod\/blob\/master\/xxx\/Dockerfile.combo\" target=\"_blank\">test\/combo<\/a>               latest          744b502e0052        2 seconds ago       269.8 MB\r\n<a title=\"Cram everything into one line\" href=\"https:\/\/github.com\/crccheck\/docker-pod\/blob\/master\/xxx\/Dockerfile.combo2\" target=\"_blank\">test\/combo2<\/a>              latest          be8f1c1de02e        About an hour ago   249.8 MB\r\n<a title=\"Cram everything into one line including extra cleaning\" href=\"https:\/\/github.com\/crccheck\/docker-pod\/blob\/master\/xxx\/Dockerfile.combo3\" target=\"_blank\">test\/combo3<\/a>              latest          da948e2838d9        About an hour ago   249.8 MB\r\n<a title=\"Move all the installs to one line\" href=\"https:\/\/github.com\/crccheck\/docker-pod\/blob\/master\/xxx\/Dockerfile.install\" target=\"_blank\">test\/install<\/a>             latest          e7cadcbb5a05        12 hours ago        269.8 MB\r\n<a title=\"Move all the installs to one line and apt clean\" href=\"https:\/\/github.com\/crccheck\/docker-pod\/blob\/master\/xxx\/Dockerfile.install_clean\" target=\"_blank\">test\/install_clean<\/a>       latest          dd1383285e85        12 hours ago        269.8 MB\r\n<a title=\"Move all the installs to one line and remove apt\/lists\" href=\"https:\/\/github.com\/crccheck\/docker-pod\/blob\/master\/xxx\/Dockerfile.install_lists\" target=\"_blank\">test\/install_lists<\/a>       latest          e55f6f8ebac8        12 hours ago        269.8 MB\r\n<a title=\"Add everything and then purge everything\" href=\"https:\/\/github.com\/crccheck\/docker-pod\/blob\/master\/xxx\/Dockerfile.purge\" target=\"_blank\">test\/purge<\/a>               latest          ef8c2aa7400b        About an hour ago   273.5 MB\r\n<a title=\"Add everything and then remove everything\" href=\"https:\/\/github.com\/crccheck\/docker-pod\/blob\/master\/xxx\/Dockerfile.remove\" target=\"_blank\">test\/remove<\/a>              latest          75e3e5c4e246        About an hour ago   273.5 MB<\/code><\/pre>\n<h2>Hypothesis: Docker&#8217;s base Ubuntu image does not need `apt-get clean`<\/h2>\n<p>I did an experiment around Docker 0.6. I think my conclusion was that `apt-get install &#8230; &amp;&amp; apt-get clean` saved a few megabytes. But I head that you didn&#8217;t need to do that. If you compare the &#8220;test\/install&#8221; and &#8220;test\/install_clean&#8221; size, you&#8217;ll see there is no difference. <strong>So you don&#8217;t need `apt-get clean`.<\/strong><\/p>\n<h2>Hypothesis: `rm -rf \/var\/lib\/apt\/lists\/*` saves some space<\/h2>\n<p>I&#8217;ve been seeing a lot of Dockerfiles lately with this line. Including lots of official Docker images. If those guys are all doing it, surely it must have some effect. <strong>Nope.<\/strong><\/p>\n<h2>Hypothesis: Combining similar lines saves space<\/h2>\n<p>There&#8217;s some overhead for each line in a Dockerfile. How significant is it? Well, it turns out it&#8217;s not. What I did find out though, is that it does save a significant amount of time and saves a lot of disk thrashing. So combining lines does not save space, but saves time.<\/p>\n<h2>Hypothesis: Combining multiple steps saves space<\/h2>\n<p>This makes sense. If you skip making checkpoints, you&#8217;re not storing intermediate states. And it turns out this is the only way to get a Docker image made from a Dockerfile smaller. But this is at the cost of readability, and more importantly, at the cost of reduced redundancy between images.<\/p>\n<h2>Hypothesis: `apt-get purge` saves some space<\/h2>\n<p>Well this hypothesis seems silly now. But I see it used now and then. Deletions do not save space.<\/p>\n<h2>Conclusion<\/h2>\n<p>Write your Dockerfiles the same way you run commands. Don&#8217;t prematurely optimize by adding extra cruft you saw someone else do. If you&#8217;re actually worried about image size, use some sort of automation to rebuild Docker images behind the scenes. Just keep that logic out of the Dockerfile. And always keep on measuring. Know your bottlenecks.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve come across tips on how to keep Docker images small and Dockerfiles with strange lines that seem to exist only to optimize image size. Well, it turns out they&#8217;re all wrong. They may have an effect with flat Docker images, but everything else (i.e. 99% of what people do), cleanup steps are just extra&hellip;<\/p>\n <a href=\"https:\/\/www.crccheck.com\/blog\/optimizing-docker-image-size-for-real\/\" title=\"Optimizing Docker Image Size For Real\" class=\"entry-more-link\"><span>Read More<\/span> <span class=\"screen-reader-text\">Optimizing Docker Image Size For Real<\/span><\/a>","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"Layout":"","footnotes":""},"categories":[50,21],"tags":[70],"class_list":["entry","author-showmewhatyougot","post-566","post","type-post","status-publish","format-standard","category-best-practices","category-case-study","tag-docker"],"_links":{"self":[{"href":"https:\/\/www.crccheck.com\/blog\/wp-json\/wp\/v2\/posts\/566","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.crccheck.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.crccheck.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.crccheck.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.crccheck.com\/blog\/wp-json\/wp\/v2\/comments?post=566"}],"version-history":[{"count":4,"href":"https:\/\/www.crccheck.com\/blog\/wp-json\/wp\/v2\/posts\/566\/revisions"}],"predecessor-version":[{"id":571,"href":"https:\/\/www.crccheck.com\/blog\/wp-json\/wp\/v2\/posts\/566\/revisions\/571"}],"wp:attachment":[{"href":"https:\/\/www.crccheck.com\/blog\/wp-json\/wp\/v2\/media?parent=566"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.crccheck.com\/blog\/wp-json\/wp\/v2\/categories?post=566"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.crccheck.com\/blog\/wp-json\/wp\/v2\/tags?post=566"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}