{"id":164403,"date":"2021-01-27T16:00:27","date_gmt":"2021-01-27T13:00:27","guid":{"rendered":"https:\/\/en.buradabiliyorum.com\/what-are-multi-stage-docker-builds-cloudsavvy-it\/"},"modified":"2021-01-27T16:00:27","modified_gmt":"2021-01-27T13:00:27","slug":"what-are-multi-stage-docker-builds-cloudsavvy-it","status":"publish","type":"post","link":"https:\/\/buradabiliyorum.com\/en\/what-are-multi-stage-docker-builds-cloudsavvy-it\/","title":{"rendered":"#What Are Multi-Stage Docker Builds? \u2013 CloudSavvy IT"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_84 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-6a29de1084c39\" 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-6a29de1084c39\" 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-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/buradabiliyorum.com\/en\/what-are-multi-stage-docker-builds-cloudsavvy-it\/#Multi-Stage_Builds_in_Action\" >Multi-Stage Builds in Action<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/buradabiliyorum.com\/en\/what-are-multi-stage-docker-builds-cloudsavvy-it\/#Advantages_of_Multi-Stage_Builds\" >Advantages of Multi-Stage Builds<\/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-multi-stage-docker-builds-cloudsavvy-it\/#Conclusion\" >Conclusion<\/a><\/li><\/ul><\/nav><\/div>\n<p><strong>&#8220;#What Are Multi-Stage Docker Builds? \u2013 CloudSavvy IT&#8221;<\/strong><\/p>\n<div id=\"article-content-area\">\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-9034\" src=\"https:\/\/www.cloudsavvyit.com\/thumbcache\/0\/0\/78cc37c3a66e5df9b2a9dc8cd64461c7\/p\/uploads\/2021\/01\/6dc7b5a0.jpeg\" alt=\"\" width=\"1602\" height=\"902\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>Multi-stage Docker builds let you write Dockerfiles with multiple <code>FROM<\/code> statements. This means you can create images which derive from several bases, which can help cut the size of your final build.<\/p>\n<p>Docker images are created by selecting a base image using the <code>FROM<\/code> statement. You then add layers to that image by adding commands to your Dockerfile.<\/p>\n<p>With <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/docs.docker.com\/develop\/develop-images\/multistage-build\/\">multi-stage builds<\/a>, you can split your Dockerfile into multiple sections. Each stage has its own <code>FROM<\/code> statement so you can involve more than one image in your builds. Stages are built sequentially and can reference their predecessors, so you can copy the output of one layer into the next.<\/p>\n<h2 id=\"multi-stage-builds-in-action\"><span class=\"ez-toc-section\" id=\"Multi-Stage_Builds_in_Action\"><\/span>Multi-Stage Builds in Action<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Let\u2019s look at how you can create a multi-stage build. We\u2019re working with a barebones PHP project which uses Composer for its dependencies and Sass for its stylesheets.<\/p>\n<p>Here\u2019s a multi-stage Dockerfile which encapsulates our entire build:<\/p>\n<div class=\"wp-geshi-highlight-wrap5\">\n<div class=\"wp-geshi-highlight-wrap4\">\n<div class=\"wp-geshi-highlight-wrap3\">\n<div class=\"wp-geshi-highlight-wrap2\">\n<div class=\"wp-geshi-highlight-wrap\">\n<div class=\"wp-geshi-highlight\">\n<div class=\"\">\n<pre class=\"de1\">FROM node:<span class=\"nu0\">14<\/span> AS sass\nWORKDIR \/example\nRUN npm install -g node-sass\nCOPY example.scss .\nRUN node-sass example.scss example.css\n\u00a0\nFROM php:<span class=\"nu0\">8.0<\/span>-apache\nCOPY --from=composer:<span class=\"nu0\">2<\/span> \/usr\/bin\/composer \/usr\/bin\/composer\nCOPY composer.json .\nCOPY composer.lock .\nRUN composer install --no-dev\nCOPY --from=sass \/example\/example.css example.css\nCOPY index.php .\nCOPY src\/ src<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>Straightaway, you\u2019ll observe we\u2019ve got two <code>FROM<\/code> statements which split our Dockerfile into two logical sections. The first stage is dedicated to compiling the Sass, while the second one focuses on combining everything together in the final container.<\/p>\n<p>We\u2019re using the <code>node-sass<\/code> implementation of Sass. We therefore start with a Node.JS base image, within which we install <code>node-sass<\/code> globally from npm. We then use <code>node-sass<\/code> to compile our stylesheet <code>example.scss<\/code> into the pure CSS <code>example.css<\/code>. The high-level summary of this stage is we take a base image, run a command and obtain an output we\u2019d like to use later in our build (<code>example.css<\/code>).<\/p>\n<p>The next stage introduces the base image for our <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: <code>php8.0-apache<\/code>. The last <code>FROM<\/code> statement in your Dockerfile defines the image your containers will end up running. Our earlier <code>node<\/code> image is ultimately irrelevant to our application\u2019s containers \u2013 it\u2019s used purely as a build-time convenience tool.<\/p>\n<p>We next use Composer to install our PHP dependencies. Composer is PHP\u2019s package manager but it\u2019s not included with the official PHP Docker images. We therefore copy the binary into our container from the dedicated Composer image.<\/p>\n<p>We didn\u2019t need a <code>FROM<\/code> statement to do this. As we\u2019re not running any commands against the Composer image, we can use the <code>--from<\/code> flag with <code>COPY<\/code> to reference the image. Ordinarily, <code>COPY<\/code> copies files from your local build context into your image; with <code>--from<\/code> and an image name, it\u2019ll create a new container using that image and then copy the specified file out of it.<\/p>\n<p>Later on, our Dockerfile uses <code>COPY --from<\/code> again, this time in a different form. Back at the top, we wrote our first <code>FROM<\/code> statement as <code>FROM node:14 AS sass<\/code>. The <code>AS<\/code> clause created a named stage called <code>sass<\/code>.<\/p>\n<p>We now <em>reference<\/em> the transient container created by this stage using <code>COPY --from=sass<\/code>. This allows us to copy our built CSS into our final image. The remainder of the steps are routine <code>COPY<\/code> operations, used to obtain our source code from our local working directory.<\/p>\n<h2 id=\"advantages-of-multi-stage-builds\"><span class=\"ez-toc-section\" id=\"Advantages_of_Multi-Stage_Builds\"><\/span>Advantages of Multi-Stage Builds<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Multi-stage builds let you create complex build routines with a single Dockerfile. Prior to their introduction, it was common for complex projects to use multiple Dockerfiles, one for each stage of their build. These then needed to be orchestrated by manually written shell scripts.<\/p>\n<p>With multi-stage builds, our entire build system can be contained in a single file. You don\u2019t need any wrapper scripts to take your project from raw codebase to final application image. A regular <code>docker build -t my-image:latest .<\/code> is sufficient.<\/p>\n<p>This simplification also provides opportunities to improve the efficiency of your images. Docker images can become large, especially if you\u2019re using a language runtime as your base.<\/p>\n<p>Take the official <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/hub.docker.com\/_\/golang\"><code>golang<\/code> image<\/a>: it\u2019s close to 300MB. Traditionally, you might copy your Go source into the image and use it to compile your binary. You\u2019d then copy your binary back to your host machine before starting another build. This one would use a Dockerfile with a lightweight base image such as <code>alpine<\/code> (about 10MB). You\u2019d add your binary back in, resulting in a much smaller image than if you\u2019d used the original <code>golang<\/code> base to run your containers.<\/p>\n<p>With multi-stage builds, this kind of system is much easier to implement:<\/p>\n<div class=\"wp-geshi-highlight-wrap5\">\n<div class=\"wp-geshi-highlight-wrap4\">\n<div class=\"wp-geshi-highlight-wrap3\">\n<div class=\"wp-geshi-highlight-wrap2\">\n<div class=\"wp-geshi-highlight-wrap\">\n<div class=\"wp-geshi-highlight\">\n<div class=\"\">\n<pre class=\"de1\">FROM golang:latest&#13;\nWORKDIR \/go&#13;\nCOPY app.go .&#13;\nRUN go build -o my-binary&#13;\n\u00a0\nFROM alpine:latest&#13;\nWORKDIR \/app&#13;\nCOPY --from=build \/go\/my-binary .&#13;\nCMD [\".\/my-binary\"]<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>In eight lines, we\u2019ve managed to achieve a procedure that would previously have needed at least three files \u2013 a <code>golang<\/code> Dockerfile, an <code>alpine<\/code> Dockerfile and a shell script to manage the inter<a href=\"https:\/\/buradabiliyorum.com\/en\/category\/social-mediaa\/\" data-internallinksmanager029f6b8e52c=\"1\" title=\"Social Media\" target=\"_blank\" rel=\"noopener\">media<\/a>ry steps.<\/p>\n<h2 id=\"conclusion\"><span class=\"ez-toc-section\" id=\"Conclusion\"><\/span>Conclusion<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Multi-stage builds can dramatically simplify the construction of complex Docker images. They let you involve multiple interconnected build steps which can pass output artifacts forwards.<\/p>\n<p>The model also promotes build efficiency. The ease with which you can reference different base images helps developers ensure the final output is as small as possible. You\u2019ll benefit from reduced storage and bandwidth costs, which can be significant when using Docker within a CI\/CD system.\n<\/p><\/div>\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.cloudsavvyit.com\/9260\/what-are-multi-stage-docker-builds\/\" target=\"_blank\" rel=\"noopener\">Source<\/a><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8220;#What Are Multi-Stage Docker Builds? \u2013 CloudSavvy IT&#8221; Multi-stage Docker builds let you write Dockerfiles with multiple FROM statements. This means you can create images which derive from several bases, which can help cut the size of your final build. Docker images are created by selecting a base image using the FROM statement. You then&#8230;<\/p>\n","protected":false},"author":1,"featured_media":164404,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"fifu_image_url":"https:\/\/www.cloudsavvyit.com\/p\/uploads\/2021\/01\/6dc7b5a0.jpeg","fifu_image_alt":"","footnotes":""},"categories":[18],"tags":[],"class_list":["post-164403","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\/164403","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=164403"}],"version-history":[{"count":0,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/164403\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media\/164404"}],"wp:attachment":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media?parent=164403"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/categories?post=164403"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/tags?post=164403"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}