Before you begin
In this tutorial, we’ll learn how to use and the difference between ADD and COPY Docker build commands. A GNU Linux/Mac OS machine and Docker will be required to follow this tutorial.
Common ADD and COPY capabilities
These commands allow you to copy files/directories from your host directly into a Docker image.
# Dockerfile COPY script_copy.sh /tmp ADD script_add.sh /tmp
Previous commands are copying script_copy.sh and script_add.sh to the /tmp directory on the Docker image:
$ docker run -it testing_add_copy ls -la /tmp > total 12 drwxrwxrwt 2 root root 4096 Oct 3 09:53 . drwxr-xr-x 35 root root 4096 Oct 3 09:53 .. -rwxrwxr-x 1 root root 415 Oct 3 09:53 script_copy.sh -rwxrwxr-x 1 root root 415 Oct 3 09:53 script_add.sh
# Dockerfile COPY my_folder /tmp # or ADD my_folder /tmp
Checking the results:
$ docker build -t testing_add_copy . && docker run -it testing_add_copy ls -la /tmp ... -rwxrwxr-x 1 root root 415 Oct 3 09:53 my_file.txt
As you can imagine, my_file.txt is the content inside of my_folder.
If you need to copy the folder itself you could do it by adding the name of the folder in the destination like the following example:
# Dockerfile COPY my_folder /tmp/my_folder # or ADD my_folder /tmp/my_folder
Checking the results:
$ docker run -it testing_add_copy ls -la /tmp ... drwxr-xr-x. 3 root root 4096 Oct 3 09:53 my_folder
If you need to copy files/directories from your host to a running container rather than to an image you can read the following post: How to copy files to or from a Docker container.
Docker ADD vs COPY
Basically Docker ADD command has two extra capabilities more than the COPY instruction:
- Automatic TAR extraction.
# Dockerfile ADD scripts.tar.gz /tmp
tar file will only be unpacked if its compression has one of the following formats: identity, gzip, bzip2 or xz.
- Allows the src to be an URL. If so, ADD will fetch files from it. If the src is a local URI the behaviour will be the same as Docker COPY.
# Dockerfile ADD http://www.example.com/script.sh /tmp
Important note! Dockerfile ADD cannot decompress and fetch a remote URL at the same time. If you try to fetch a remote compressed file, will be not decompressed just fetched.
Docker COPY vs ADD
Following Best practices for writing Dockerfiles we should use ADD only when TAR extraction capability is needed otherwise is better to use COPY for the following reasons:
- TAR extraction and remote URL support sometimes are not obvious and could easily end up to a mistake.
- Fetching files and delete them need an extra layer. To prevent that is recommended to use GNU Wget or CURL instead of ADD instruction.
- Docker COPY command can be used together with
--fromin a multi-stage build scenario to copy files from previous build stages to the current build stage. Example:
# Dockerfile FROM node AS builder WORKDIR /opt/app RUN node -v RUN npm -v COPY . /opt RUN npm init -y ... FROM nginx:1.17-alpine COPY --from=builder /opt/app /usr/share/nginx/html ...
Previous command copies the app folder build in previous stage to the current one in a folder ready to be serverd by Nginx. Using multi-stage build and
COPY --frommakes the resulting image smaller because it doesn’t include all the redundant files as a result of running node and npm build packages.
- Having said all that, COPY is simpler than ADD resulting in a more controlled behaviour.
This post has been all about copying files during Docker build time. If you need to copy files once the containers are running we have another post called “How to copy files to or from a Docker container”.
Finally, make sure to use a .dockerignore file to define a better Docker build context.
Finally, you should definitely take a look at these books to fuel your Docker knowledge: