What is the difference between the 'COPY' and 'ADD' commands in a Dockerfile?

When you create a Dockerfile, you can use two different commands to build your context. Building a context means including the files and directories that you want from your local machine, to be in your container when it’s created. These files may be directories in your local machine, a URL from which you want to download files, or a compressed tarball file that you want to include as it is or after extracting the tarball file.

We can use two different instructions to add the files from the build context in the local machine to the Docker container. These are the COPY and ADD instructions. Although they perform almost the same tasks, however, there are slight differences in the way they work. So, the question here is why do we have two different commands to perform the same work and which one should we use?

In this article, we will discuss the same. So without any further ado, let’s discuss the use-cases for both the ADD and COPY instructions.

ADD Instruction

The ADD instruction that we use in a Dockerfile is a comparatively older instruction and has been with Docker from its inception. The ADD instruction can do things more than just copying the directories or files from the localhost. We can use the ADD instruction to pull the files or directories from externals links/URLs such as Github, Bitbucket, etc. The ADD instruction can also be used to extract compressed files such as archives or tarball files. However, sometimes, it might cause a problem if you don’t actually want to extract the archives.

The syntax of the ADD instruction is -

$ ADD <source path> <destination path>

Some important use-cases of the ADD instruction are -

  • To copy the files and directories from the local machine to the images.

For instance, if we want to simply copy the files from the /home/user/Dekstop/app directory in our local host system to the /app directory inside the Docker image, we can embed this instruction inside the Dockerfile-

$ ADD /home/user/Desktop/app /app

In such a case, the daemon only copies the contents of the source directory the destination directory including the metadata. Since we have not mentioned a trailing slash, it won’t copy the directory itself.

  • To extract the tarball files that are stored locally.

The ADD instruction can also be used to extract the compressed tarball files or archives that have the following formats - bzip2, xz, gzip2. The ADD instruction automatically extracts the contents in a directory that is created inside the destination folder in the Docker container. For example, if we want to extract the sample.tar.gz file to the /app directory inside the container, we can use the following command.

$ ADD /home/user/sample.tar.gz /app

The is exactly similar to the operation of the tarball command to extract a tarball in our host machine.

  •  To download a directory or a file from a URL

This feature of the ADD instruction is similar to the working of the wget -P command. When we try to build a Docker image, we can use the ADD instruction to directly download a file from a given URL and store it in a location inside the container. The command to do so is -

https://www.asamplelink.com/test/sampledocuments/mysamplefile.pdf /app

When the image built is completed, we can get access to these files when the container is launched.

COPY Instruction

We can consider the COPY instruction in a Dockerfile as an evolved version of the ADD instruction. The COPY instruction was created to remove the confusion among Docker developers. The only function of the COPY instruction is to copy files from the source directory on the host machine to the destination directory on the container. If we mention the source as a tarball file, it does not extract it inside the container but simply copies it as it is.

Also, the COPY instruction does not take a URL parameter as a source. The syntax to copy files using the COPY instruction is -

$ COPY <source> <destination>

Example -

$ COPY /home/user/sample/files /app

Final Thoughts!

To conclude, if you wish to simply copy the files and directories from your localhost to the container environment, it’s recommended that you use only the COPY instruction. You must avoid using the ADD instruction wherever possible. If you want to extract or download files, you can use the RUN instruction along with normal Linux commands.

In this article, we discussed how to use ADD and COPY Dockerfile instructions, their use-cases, the fundamental differences between the two along with some hands-on examples and commands.