Difference between the COPY and ADD commands in a Dockerfile
When creating Dockerfiles, it’s often necessary to transfer files from the host system into the Docker image. These could be property files, native libraries, or other static content that our applications will require at runtime.
The Dockerfile specification provides two ways to copy files from the source system into an image: the COPY and ADD directives.
In this article, we’ll look at the difference between them and when it makes sense to use each one.
Sometimes you see COPY or ADD being used in a Dockerfile, but 99% of the time you should be using COPY. Here’s why?
COPY and ADD are both Dockerfile instructions that serve similar purposes. They let you copy files from a specific location into a Docker image.
COPY takes in a src and destination. It only lets you copy in a local or directory from your host (the machine-building the Docker image) into the Docker image itself.
COPY <src> <dest>
ADD lets you do that too, but it also supports 2 other sources. First, you can use a URL instead of a local file/directory. Secondly, you can extract tar from the source directory into the destination.
ADD <src> <dest>
In most cases, if you’re using a URL, you download a zip file and then use the RUN command to extract it. However, you might as well just use RUN and curl instead of ADD here, so you chain everything into 1 RUN command to make a smaller Docker image.
A valid use case for ADD is when you want to extract a local tar file into a specific directory in your Docker image. This is exactly what the Alpine image does with ADD rootfs.tar.gz /.
If you are copying local files to your Docker image, always use COPY because it’s more explicit.
While functionality is similar, the ADD directive is more powerful in two ways:
- It can handle remote URLs
- It can also auto-extract tar files.
Let’s look at these more closely.
First, the ADD directive can accept a remote URL for its source argument. The COPY directive, on the other hand, can only accept local files.
Note that using ADD to fetch remote files and copying is not typically ideal.
This is because the file will increase the overall Docker Image size. Instead, we should use curl or wget to fetch remote files and remove them when no longer needed.
Second, the ADD directive will automatically expand tar files into the image file system. While this can reduce the number of Dockerfile steps required to build an image, it may not be desired in all cases.|
Note that the auto-expansion only occurs when the source file is local to the host system.
When to use ADD or COPY :
According to the Dockerfile best practices guide, we should always prefer COPY over ADD unless we specifically need one of the two additional features of ADD.
As noted above, using ADD command automatically expands tar files and certain compressed formats, which can lead to unexpected files being written to the file system in our images.
In this article, you’ve seen the two primary ways to copy files into a Docker image: ADD and COPY. While functionally similar, the COPY directive is preferred for most cases. This is because the ADD directive provides additional functionality that should be used with caution and only when needed.