Docker ADD vs. COPY: What are the Differences?

January 25, 2024

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 vs. COPY: What are the differences?

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.

The COPY command in a Dockerfile that creates an Apache server image.

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.

An output of the docker build command shows the COPY command as the second step in 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.

Was this article helpful?
YesNo
Marko Aleksic
Marko Aleksić is a Technical Writer at phoenixNAP. His innate curiosity regarding all things IT, combined with over a decade long background in writing, teaching and working in IT-related fields, led him to technical writing, where he has an opportunity to employ his skills and make technology less daunting to everyone.
Next you should read
How to Commit Changes to a Docker Image with Examples
February 14, 2024

Docker allows users to run a container based on an existing image. This feature is both time efficient and...
Read more
Docker Image vs Container: The Major Differences
October 31, 2019

Docker images and containers are elements in Docker's platform-as-a-service software. They are both essential...
Read more
How to Create Docker Image with Dockerfile
October 23, 2019

A Dockerfile offers a simpler and faster way of creating Docker images. They go through the script with all...
Read more
How To Remove Docker Images, Containers, Networks & Volumes
February 7, 2019

Docker allows users to create a container in which an application or process can run. In this guide, you will...
Read more