Every developer and every team faces confusion about COPY and ADD in the Dockerfile at some point. When I get this question, first I usually give the technical background, which is this:

Both **ADD** and **COPY** copy files and directories from the host machine into a Docker image, the difference is that **ADD** can also extract and copy local tar archives and it can also download files from URLs (a.k.a. the internet), and copy them into the Docker image. The best practice is to use **COPY**.

So COPY equals ADD minus the unpacking and URL fetching features. COPY is the preferred way, except if you unpack a local tar archive into a Docker image and you are certain that the local archive has the right format.

You can understand why this is the case looking at some background info. Read on…

Why COPY is Preferred

The core purpose of ADD and COPY is to let Dockerfile developers copy files and directories from the host machine into the Docker image during image build.

Extracting archives and downloading files from the internet are common use-cases, these features are built into ADD.

The uncompression feature is described in the official documentation as follows:

If  <src> is a local tar archive in a recognized compression format (identity, gzip, bzip2 or xz) then it is unpacked as a directory.

The following note on the same page further explains the behavior:

Note: Whether a file is identified as a recognized compression format is done solely based on the contents of the file, not the name of the file. For example, if an empty file happens to end with  .tar.gz this will not be recognized as a compressed file, and will not generate any kind of decompression error message, rather the file will simply be copied to the destination.

This means that your final outcome depends on the contents of the file you intend to copy, and you don’t get warnings if something goes wrong. This may make your build pipeline unpredictable.

_To make life more reliable, we have the _**_COPY_**_ instruction, which is __"the same as _[**_ADD_**](https://github.com/moby/moby/blob/670c8696a29825b23208496bd4d8e88b5faa7773/builder/dispatchers.go#L77), but without the tar and URL handling". **COPY** does one thing and it does it well.

#docker #kubernetes #cloud native #add #copy #cloud

Shall I Use ADD or COPY in the Dockerfile, and What's the Difference?
1.25 GEEK