{"id":482003,"date":"2022-08-07T09:02:11","date_gmt":"2022-08-07T06:02:11","guid":{"rendered":"https:\/\/en.buradabiliyorum.com\/how-to-use-multiple-docker-build-contexts-to-streamline-image-assembly\/"},"modified":"2022-08-07T09:02:11","modified_gmt":"2022-08-07T06:02:11","slug":"how-to-use-multiple-docker-build-contexts-to-streamline-image-assembly","status":"publish","type":"post","link":"https:\/\/buradabiliyorum.com\/en\/how-to-use-multiple-docker-build-contexts-to-streamline-image-assembly\/","title":{"rendered":"#How to Use Multiple Docker Build Contexts to Streamline Image Assembly"},"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-6a2a6072be6e4\" 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-6a2a6072be6e4\" 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\/how-to-use-multiple-docker-build-contexts-to-streamline-image-assembly\/#%E2%80%9CHow_to_Use_Multiple_Docker_Build_Contexts_to_Streamline_Image_Assembly%E2%80%9D\" >&#8220;How to Use Multiple Docker Build Contexts to Streamline Image Assembly&#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\/how-to-use-multiple-docker-build-contexts-to-streamline-image-assembly\/#Purpose_of_the_Build_Context\" >Purpose of the Build Context<\/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\/how-to-use-multiple-docker-build-contexts-to-streamline-image-assembly\/#Using_Multiple_Build_Contexts\" >Using Multiple Build Contexts<\/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\/how-to-use-multiple-docker-build-contexts-to-streamline-image-assembly\/#Priority_Order\" >Priority Order<\/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\/how-to-use-multiple-docker-build-contexts-to-streamline-image-assembly\/#Remote_URLs\" >Remote URLs<\/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\/how-to-use-multiple-docker-build-contexts-to-streamline-image-assembly\/#Mounting_Files_From_a_Build_Context\" >Mounting Files From a Build Context<\/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\/how-to-use-multiple-docker-build-contexts-to-streamline-image-assembly\/#Precisely_Rebuilding_Images\" >Precisely Rebuilding Images<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-use-multiple-docker-build-contexts-to-streamline-image-assembly\/#Conclusion\" >Conclusion<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n<h1><span class=\"ez-toc-section\" id=\"%E2%80%9CHow_to_Use_Multiple_Docker_Build_Contexts_to_Streamline_Image_Assembly%E2%80%9D\"><\/span>&#8220;How to Use Multiple Docker Build Contexts to Streamline Image Assembly&#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\u2019s concept of the \u201cbuild context\u201d is one of its <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/stackoverflow.com\/questions\/27068596\/how-to-include-files-outside-of-dockers-build-context\">most restrictive and misunderstood<\/a> characteristics. The build context defines the local files and folders you can reference in your Dockerfile. Content outside it cannot be used, which often hinders complex build procedures.<\/p>\n<p>BuildKit v0.8 improves this situation by letting you use multiple contexts with each build you perform. This makes it easier to reference files that may reside in completely separate locations, such as a file within your working directory and a dependency at a remote URL.<\/p>\n<p>In this article we\u2019ll explain why multiple build contexts are useful and how you can use them with the latest Docker CLI release. First let\u2019s recap what the build context is and why so many people have run into issues in the past.<\/p>\n<h2 id=\"purpose-of-the-build-context\"><span class=\"ez-toc-section\" id=\"Purpose_of_the_Build_Context\"><\/span>Purpose of the Build Context<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Docker is daemon-based. The process that runs your image builds is independent of the CLI process that issues the command. The daemon could be located on a remote host which can\u2019t directly access your machine\u2019s filesystem.<\/p>\n<p>The build context refers to the files that are transferred to the Docker daemon when a build occurs. This is why only content within the context can be referenced by your Dockerfile.<\/p>\n<p>It\u2019s common to run <code>docker build<\/code> with <code>.<\/code> as its argument, which makes your working directory the build context:<\/p>\n<pre>docker build -t my-website:latest .<\/pre>\n<p>This permits references to any path inside your working directory:<\/p>\n<pre>FROM httpd:latest&#13;\nCOPY index.html \/var\/www\/html\/index.html<\/pre>\n<p>You can\u2019t reach out to copy anything <em>above<\/em> the working directory in your filesystem:<\/p>\n<pre>FROM httpd:latest&#13;\nCOPY index.html \/var\/www\/html\/index.html&#13;\nCOPY ..\/company-css\/company.css \/var\/www\/html\/company.css<\/pre>\n<p>Every file you need in your container image must exist under a single directory that you can use as the build context. This can be problematic in situations like the one shown above, where you want to pull in dependencies from sources that aren\u2019t in your project\u2019s tree.<\/p>\n<h2 id=\"using-multiple-build-contexts\"><span class=\"ez-toc-section\" id=\"Using_Multiple_Build_Contexts\"><\/span>Using Multiple Build Contexts<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Multiple build contexts <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/www.docker.com\/blog\/dockerfiles-now-support-multiple-build-contexts\">are now supported<\/a> in BuildKit v0.8 and newer when you opt-in to Dockerfile syntax v1.4. These releases are shipped with the Docker CLI starting from version 20.10.13. You should be able to use them today if you\u2019re running the latest version of Docker.<\/p>\n<p>You must build your image with BuildKit to use multiple contexts. They aren\u2019t supported by the legacy builder. Use the <code>docker buildx build<\/code> command instead of plain <code>docker build<\/code>:<\/p>\n<pre>$ docker buildx build -t my-website:latest .<\/pre>\n<p>Now you can use the <code>--build-context<\/code> flag to define multiple named build contexts:<\/p>\n<pre>$ docker buildx build -t my-website:latest . \\&#13;\n    --build-context company-css=..\/company-css \\&#13;\n    --build-context company-js=..\/company-js \\<\/pre>\n<p>Adjust your Dockerfile to reference content from these contexts:<\/p>\n<pre>#syntax=docker\/dockerfile:1.4&#13;\nFROM httpd:latest&#13;\nCOPY index.html \/var\/www\/html\/index.html&#13;\nCOPY --from=company-css \/company.css \/var\/www\/html\/company.css&#13;\nCOPY --from=company-js \/company.js \/var\/www\/html\/company.js<\/pre>\n<p>This illustrates how you can copy in files and folders that lie outside your main build context, irrespective of their position in your filesystem tree.<\/p>\n<p>The Dockerfile v1.4 syntax declaration is required to enable support for the feature. You can then use the <code>--from<\/code> option with <code>ADD<\/code> and <code>COPY<\/code> instructions to pull in files from named build contexts, similarly to referencing a resource in an earlier build stage.<\/p>\n<h2 id=\"priority-order\"><span class=\"ez-toc-section\" id=\"Priority_Order\"><\/span>Priority Order<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Multiple build contexts modify the resource resolution order for the <code>--from<\/code> flag. Docker will now match the key you supply (<code>--from=key<\/code>) using the following procedure:<\/p>\n<ul>\n<li>Look for a named build context set with the <code>--build-context<\/code> flag.<\/li>\n<li>Look for an earlier build stage created with <code>FROM my-image:latest AS stage-name<\/code>.<\/li>\n<li>Create a new inline build stage using the given key as the stage\u2019s image.<\/li>\n<\/ul>\n<p>This means you can use named contexts to override remote dependencies defined using build stages.<\/p>\n<p>Consider this example:<\/p>\n<pre>#syntax=docker\/dockerfile:1.4&#13;\nFROM my-org\/company-scss:latest AS css&#13;\nRUN sass company.scss company.css&#13;\n&#13;\nFROM httpd:latest&#13;\nCOPY index.html \/var\/www\/html\/index.html&#13;\nCOPY --from=css \/company.css \/var\/www\/html\/company.css<\/pre>\n<p>This Docker image pulls in some remote resources from another shared Docker image. This can create difficulties when you\u2019re testing your project \u2013 there could be a bug in the dependency which you want to quickly patch.<\/p>\n<p>Named build contexts let you override the <code>css<\/code> stage name to supply a local file instead:<\/p>\n<pre>$ docker buildx build -t my-website:latest . --build-context css=css\/<\/pre>\n<p>This will copy your working directory\u2019s <code>css\/company.css<\/code> file into the final image, instead of the version supplied by the <code>my-org\/company-scss:latest<\/code> dependency.<\/p>\n<p>The resolution order means overrides can be <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>lied even if your image doesn\u2019t use named build stages. By defining a build context with the same name as an image, your Dockerfile will pull in content from that context, instead of the original registry image.<\/p>\n<pre>$ docker buildx build -t my-website:latest . --build-context my-org\/company-scss:latest=css\/<\/pre>\n<h2 id=\"remote-urls\"><span class=\"ez-toc-section\" id=\"Remote_URLs\"><\/span>Remote URLs<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Named build contexts support all the sources that <code>docker build<\/code> already accepted:<\/p>\n<ul>\n<li><code>--build-context my-context=..\/local\/path<\/code> \u2013 A path in your filesystem.<\/li>\n<li><code>--build-context my-context=https:\/\/github.com\/user\/repo.git<\/code> \u2013 A remote Git repository.<\/li>\n<li><code>--build-context my-context=https:\/\/example.com\/data.tar<\/code> \u2013 A remote tarball provided by an HTTP server.<\/li>\n<li><code>--build-context my-context=docker-image:\/\/busybox:latest<\/code> \u2013 The content of another Docker image.<\/li>\n<\/ul>\n<p>Remote sources further simplify dependency overrides. You can point directly to a forked Git repository or a different Docker image tag, all while leaving your Dockerfile unchanged.<\/p>\n<h2 id=\"mounting-files-from-a-build-context\"><span class=\"ez-toc-section\" id=\"Mounting_Files_From_a_Build_Context\"><\/span>Mounting Files From a Build Context<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Named build contexts work with <code>RUN<\/code> instructions too. You can use <code>--mount=from<\/code> to run an executable from another build context.<\/p>\n<pre>#syntax=docker\/dockerfile:1.4&#13;\nRUN --mount=from=name-of-build-context demo-executable<\/pre>\n<p>This mounts the file without copying it into the current layer, helping to improve performance. <code>demo-executable<\/code> won\u2019t exist in the final image.<\/p>\n<h2 id=\"precisely-rebuilding-images\"><span class=\"ez-toc-section\" id=\"Precisely_Rebuilding_Images\"><\/span>Precisely Rebuilding Images<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Another use case for named build contexts concerns rebuilding images in the future. Dockerfiles with instructions like <code>FROM alpine:3.15<\/code> aren\u2019t fully reproducible. Image tags are mutable so <code>alpine:3.15<\/code> may contain different content in the future, after a new patch is released. This means rebuilt images aren\u2019t guaranteed to produce the same layers as their original versions.<\/p>\n<p>You can solve this problem by inspecting the first build\u2019s metadata to discover the exact base image that was used:<\/p>\n<pre>$ docker buildx imagetools inspect --format '{{json .BuildInfo}}' my-image:latest&#13;\n{&#13;\n    ...&#13;\n    \"sources\": [&#13;\n        {&#13;\n            \"type\": \"docker-image\",&#13;\n            \"ref\": \"docker.io\/library\/alpine:3.15\",&#13;\n            \"pin\": \"sha256:4edbd2beb5f78b1014028f4fbb99f3237d9561100b6881aabbf5acce2c4f9454\"&#13;\n        }&#13;\n    ]&#13;\n    ...&#13;\n}<\/pre>\n<p>Now you can define a named build context called <code>alpine:3.15<\/code> that points to the exact version that was previously used:<\/p>\n<pre>$ docker buildx build -t my-image:latest . --build-context alpine:3.15=docker-image:\/\/alpine3.15@4edbd2beb5f78b1014028f4fbb99f3237d9561100b6881aabbf5acce2c4f9454<\/pre>\n<p>This simplifies creating a precise rebuild of a previously created image, without having to modify its Dockerfile.<\/p>\n<h2 id=\"conclusion\"><span class=\"ez-toc-section\" id=\"Conclusion\"><\/span>Conclusion<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Multiple build contexts give you more options for organizing complex Dockerfiles and project directory trees. They solve the longstanding usability challenges that you may experience with a single build context.<\/p>\n<p>Named build contexts let you include out-of-tree dependencies and perform ad-hoc overrides. They work well alongside Docker\u2019s existing named build stages. Combining the two features helps you create modular Dockerfiles that can be customized at build time.<\/p>\n<p>You can get started with multiple build contexts today by updating to Docker 20.10.13 or newer and using <code>docker buildx<\/code> to create your images. Standalone <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/github.com\/moby\/buildkit\">BuildKit<\/a> distributions are available too when you don\u2019t want to install the whole Docker CLI.<\/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\/how-to-use-multiple-docker-build-contexts-to-streamline-image-assembly\/\" target=\"_blank\" rel=\"noopener\">Source<\/a><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8220;How to Use Multiple Docker Build Contexts to Streamline Image Assembly&#8221; Docker\u2019s concept of the \u201cbuild context\u201d is one of its most restrictive and misunderstood characteristics. The build context defines the local files and folders you can reference in your Dockerfile. Content outside it cannot be used, which often hinders complex build procedures. BuildKit v0.8&#8230;<\/p>\n","protected":false},"author":1,"featured_media":482004,"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-482003","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\/482003","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=482003"}],"version-history":[{"count":0,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/482003\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media\/482004"}],"wp:attachment":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media?parent=482003"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/categories?post=482003"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/tags?post=482003"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}