Introduction
ADD
and COPY
are Docker commands for copying files and directories to a Docker image using a Dockerfile. Although there are differences in the scope of their function, the commands perform the same task.
This article compares Docker ADD
vs. COPY
and advises when to use each command.
Docker ADD Command Overview
The ADD
command precedes COPY
, as it has always been part of Docker. The command copies files and directories to a Docker image filesystem.
The basic syntax for the ADD
command is:
ADD [source] … [destination]
The syntax includes one or more [source]
files, directories, or URLs, followed by the [destination]
directory on the image's filesystem. If the source is a directory, the ADD
command copies everything, including file system metadata.
To add a locally available file to an image directory, type:
ADD [path-to-local-file] [destination]
For example:
ADD /home/test/myapp/code.php /root/myapp
Note: The source files and directories must be in the context directory, i.e., the directory where the user will run the docker build
command.
To copy files from a URL, execute the following command:
ADD [file-url] [destination]
ADD
can also copy compressed (tarball) files and automatically extract the content at the destination. This feature only applies to locally stored compressed files and directories.
The command extracts a compressed source only if it is in a recognized compression format (based on the file's contents, not the extension). The recognized compression formats include identity, gzip, bzip, and xz.
Docker COPY Command Overview
Docker introduced COPY
as an additional command for duplicating content to address some of the ADD
command's functionality issues. The main problem with ADD
is the automatic extraction of the compressed files, which may result in a broken Docker image. This happens if a user does not anticipate the command's behavior.
The COPY
command's only assigned function is to copy the specified files and directories in their existing format. This limitation affects the compressed files, which are copied as-is, i.e., without extraction.
Furthermore, COPY
works with locally stored files only. It cannot be used with URLs to copy external files to an image.
To use COPY
, follow the basic command format:
COPY [source] … [destination]
For example, type the following command to copy index.html from the main build context directory to /usr/local/apache2/htdocs in the image:
COPY index.html /usr/local/apache2/htdocs
The image below shows the command in a Dockerfile.
Docker executes the command when the user starts the build process with docker build
:
docker build -t [image-name] .
The following image shows COPY
as the second step of the image-building process.
Docker ADD vs. COPY Command: What Are the Differences?
In the part where their use cases overlap, ADD
and COPY
work similarly. Both commands copy the contents of the locally available file or directory to the filesystem inside a Docker image.
However, while COPY
has no other functionalities, ADD
can extract compressed files and copy files from a remote location via a URL.
Why Use COPY Instead of ADD in Dockerfile?
Docker's official documentation notes that users should always choose COPY
over ADD
since it is a more transparent and straightforward command.
The ADD
command use is discouraged for all cases except when the user wants to extract a local compressed file. For copying remote files, the run command combined with wget or curl is safer and more efficient. This method avoids creating an additional image layer and saves space.
The following example shows the Dockerfile instruction that uses RUN
to download a compressed package from a URL, extract the content, and clean up the archive.
RUN curl http://source.file/package.file.tar.gz \
| tar -xjC /tmp/ package.file.tar.gz \
&& make -C /tmp/ package.file.tar.gz
Conclusion
This article compared ADD
and COPY
, the two commands used in Dockerfile to copy files and directories into a Docker image. We presented COPY
as the recommended choice and showed how to minimize ADD
usage in your Dockerfiles.
To learn more about creating Dockerfiles, check out the article on How to Create Docker Images With Dockerfile.