{"id":332860,"date":"2021-08-31T15:34:33","date_gmt":"2021-08-31T12:34:33","guid":{"rendered":"https:\/\/en.buradabiliyorum.com\/whats-the-difference-between-copy-and-add-in-dockerfiles-cloudsavvy-it\/"},"modified":"2021-08-31T15:34:33","modified_gmt":"2021-08-31T12:34:33","slug":"whats-the-difference-between-copy-and-add-in-dockerfiles-cloudsavvy-it","status":"publish","type":"post","link":"https:\/\/buradabiliyorum.com\/en\/whats-the-difference-between-copy-and-add-in-dockerfiles-cloudsavvy-it\/","title":{"rendered":"#What\u2019s the Difference Between COPY and ADD in Dockerfiles? \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-6a2e265845202\" 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-6a2e265845202\" 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\/whats-the-difference-between-copy-and-add-in-dockerfiles-cloudsavvy-it\/#COPY\" >COPY<\/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\/whats-the-difference-between-copy-and-add-in-dockerfiles-cloudsavvy-it\/#ADD\" >ADD<\/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\/whats-the-difference-between-copy-and-add-in-dockerfiles-cloudsavvy-it\/#Summary\" >Summary<\/a><\/li><\/ul><\/nav><\/div>\n<p><strong>&#8220;#What\u2019s the Difference Between COPY and ADD in Dockerfiles? \u2013 CloudSavvy IT&#8221;<\/strong><\/p>\n<div id=\"article-content-area\">\n<img loading=\"lazy\" decoding=\"async\" class=\"type:primaryImage aligncenter size-full wp-image-9034\" srcset=\"https:\/\/www.cloudsavvyit.com\/p\/uploads\/2021\/01\/6dc7b5a0.jpeg?width=398&amp;trim=1,1&amp;bg-color=000&amp;pad=1,1 400w, https:\/\/www.cloudsavvyit.com\/p\/uploads\/2021\/01\/6dc7b5a0.jpeg?width=1198&amp;trim=1,1&amp;bg-color=000&amp;pad=1,1 1200w\" sizes=\"auto, 400w, 1200w\" src=\"https:\/\/www.cloudsavvyit.com\/p\/uploads\/2021\/01\/6dc7b5a0.jpeg?width=1198&amp;trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"\" width=\"1602\" height=\"902\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p><code>ADD<\/code> and <code>COPY<\/code> are two similar <code>Dockerfile<\/code> instructions which let you add content to your images at build time. Whereas <code>COPY<\/code> is a straightforward source to destination copy, <code>ADD<\/code> includes extra functionality for working with archives and remote URLs.<\/p>\n<h2 id=\"copy\"><span class=\"ez-toc-section\" id=\"COPY\"><\/span>COPY<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p><a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/docs.docker.com\/engine\/reference\/builder\/#copy\"><code>COPY<\/code><\/a> is the simpler of the two instructions. It accepts two arguments, a source and destination:<\/p>\n<pre>COPY example.txt \/example\/dir\/example.txt<\/pre>\n<p>The source path will be copied from your Docker host into the container\u2019s filesystem. The built image will include the copied file or directory at the specified destination path.<\/p>\n<p><code>COPY<\/code> works with all files and directories but source paths are restricted to those within your active build context. The context is set when you run <code>docker build<\/code>:<\/p>\n<pre>docker build .&#13;\n&#13;\n# OR&#13;\n&#13;\ndocker build \/path\/to\/context<\/pre>\n<p>The instruction automatically creates the destination directory in the container when it doesn\u2019t already exist. If you include a trailing slash (<code>\/<\/code>), Docker treats the destination as a directory and will place the source file inside it.<\/p>\n<p>You can use wildcards such as <code>*.jpg<\/code> in the source path destination to match a set of files. These expressions will be parsed using the Go <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/redirect.viglink.com\/?key=204a528a336ede4177fff0d84a044482&amp;u=https%3A%2F%2Fpkg.go.dev%2Fpath%2Ffilepath%23Match\"><code>filepath<\/code> matcher<\/a>.<\/p>\n<p>Copied files have a UID and GID of 0 by default. This can be customized with the optional <code>--chown<\/code> flag which accepts UIDs, GIDs, and names. It runs <code>chown<\/code> on the copied files once they\u2019re inside the container:<\/p>\n<pre>COPY --chown=my-user:my-group example.txt \/example.txt<\/pre>\n<p><code>COPY<\/code> also supports a <code>--from<\/code> flag. This modifies the source path to refer to <em>another<\/em> container image, instead of your local build context. It also works with multi-stage builds to pull in artifacts created by earlier build stages.<\/p>\n<pre># Copies \/usr\/bin\/composer from the composer:latest image&#13;\nCOPY --from=composer:latest \/usr\/bin\/composer \/usr\/bin\/composer&#13;\n&#13;\n# Multi-stage build example&#13;\n# Stage 1: Copies example.scss from working directory into node:latest image&#13;\n# Stage 2: Copies example.css built in stage 1 into the final image (based on httpd:latest)&#13;\nFROM node:latest AS sass&#13;\nCOPY example.scss .&#13;\nRUN npm install -g node-sass &amp;&amp; node-sass example.scss example.css&#13;\nFROM httpd:latest&#13;\nCOPY --from=sass \/example.css example.css<\/pre>\n<p>The <code>--from<\/code> flag must refer to a named stage that\u2019s listed earlier in the <code>Dockerfile<\/code>. When there\u2019s no matching stage, Docker assumes you\u2019re referencing an image instead. You\u2019ll hit a build error if the image can\u2019t be pulled.<\/p>\n<h2 id=\"add\"><span class=\"ez-toc-section\" id=\"ADD\"><\/span>ADD<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p><a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/docs.docker.com\/engine\/reference\/builder\/#add\"><code>ADD<\/code><\/a> has the same syntax as <code>COPY<\/code>, accepting source and destination paths. There\u2019s no support for <code>--from<\/code> but you can use <code>--chown<\/code>.<\/p>\n<p>Unlike <code>COPY<\/code>, <code>ADD<\/code> is capable of <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\">download<\/a>ing remote file URLs. Specifying a publicly accessible URL as the source path will download that file and add it to the container image. The destination path\u2019s modified time (<code>mtime<\/code>) will be set to the value of the <code>Last-Modified<\/code> header in the download\u2019s HTTP response.<\/p>\n<p><code>ADD<\/code> can also extract tar archives, including archives compressed with gzip, bzip2, and xz. Specifying a compatible archive as the source path will unpack its contents into the specified container directory. The existing contents of the directory will be retained.<\/p>\n<p>Archive detection is based on the actual file contents, not the filename or extension. You can use any genuine archive file without naming it <code>.tar<\/code>, <code>.tar.gz<\/code> or <code>.tar.xz<\/code>.<\/p>\n<p>The ability to automatically extract archives simplifies adding software packages distributed as tar files to your container images. Supplying a tar path to <code>COPY<\/code> would copy the compressed archive file as-is, not its contents. You\u2019d need to use a <code>RUN<\/code> instruction to manually decompress the file.<\/p>\n<p>The behaviors around <code>COPY<\/code> apply to <code>ADD<\/code> to. Except for remote URLs, source paths must exist in your build context. The container\u2019s destination path will be automatically created when it doesn\u2019t exist using Docker\u2019s <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/docs.docker.com\/engine\/reference\/builder\/#add\">rules<\/a> for path resolution.<\/p>\n<h2 id=\"summary\"><span class=\"ez-toc-section\" id=\"Summary\"><\/span>Summary<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p><code>COPY<\/code> and <code>ADD<\/code> are two closely related but distinctly different instructions you can use when writing a <code>Dockerfile<\/code>. As their feature sets overlap, you might be wondering which is the \u201cbest\u201d to use by default.<\/p>\n<p>According to Docker\u2019s own <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/docs.docker.com\/develop\/develop-images\/dockerfile_best-practices\/#add-or-copy\">best practices guide<\/a>, you should reach for <code>COPY<\/code> unless you need the extra capabilities of <code>ADD<\/code>. <code>ADD<\/code> is an opaque operation that adds magic to the copying process.<\/p>\n<p>Only using <code>ADD<\/code> when it\u2019s actually needed helps to communicate your intentions. Otherwise, you risk getting team members into the habit of using <code>ADD<\/code> which could have disastrous consequences. An unintentional <code>ADD my-archive.tar .<\/code> instead of <code>COPY my-archive.tar<\/code> could cause confusion and broken builds when the archive\u2019s contents show up in your container, instead of the archive itself.<\/p>\n<p>You should also carefully consider when it\u2019s appropriate to use <code>ADD<\/code> with remote URLs. It can be more efficient to use <code>curl<\/code> or <code>wget<\/code> with a <code>RUN<\/code> instruction as this helps facilitate image layer caching. An <code>ADD<\/code> instruction will always invalidate the cache for all following build stages when the file at a remote URL changes.<\/p>\n<p>Where possible, it\u2019s good practice to delete copied files after they\u2019ve been used. If you\u2019re downloading or extracting a software installer, deleting the one-time binary after you\u2019ve run it will help to slim down your final image.\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\/14005\/whats-the-difference-between-copy-and-add-in-dockerfiles\/\" target=\"_blank\" rel=\"noopener\">Source<\/a><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8220;#What\u2019s the Difference Between COPY and ADD in Dockerfiles? \u2013 CloudSavvy IT&#8221; ADD and COPY are two similar Dockerfile instructions which let you add content to your images at build time. Whereas COPY is a straightforward source to destination copy, ADD includes extra functionality for working with archives and remote URLs. COPY COPY is the&#8230;<\/p>\n","protected":false},"author":1,"featured_media":332861,"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-332860","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\/332860","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=332860"}],"version-history":[{"count":0,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/332860\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media\/332861"}],"wp:attachment":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media?parent=332860"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/categories?post=332860"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/tags?post=332860"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}