Docker: Difference between ADD and COPY commands in a Dockerfile ?
This tutorial explains you the difference between ADD and COPY commands usage in a Dockerfile. Though ADD and COPY functionalities are similar there is some difference and COPY is preferred. Let’s see in detail with examples.
Difference between ADD and COPY commands – Dockerfile
Let’s consider the following sample Dockerfile. Here we use base ubuntu image on top of it we are going to install openssh-server and configure the port inside the container using the local file “sshd_config” that is copied in which we have modified port from 22 -> 2222.
First, Get the default sshd_config and keep it in your project directory as shown below. Then do $ vim sshd_config and change port from 22 -> 2222.
Then, create any sample tar file and place it inside your project directory as shown below for our exercise.
<Project Directory> $ ls Dockerfile sample_tar.tar sshd_config
COPY instruction
COPY instruction is used here to basically copy local files (modified sshd_config) in to the container, so that sshd daemon (/usr/sbin/sshd -D ) while running it will run on port 2222 instead of default port 22.
Dockerfile
FROM ubuntu //STEP 1 MAINTAINER Sneppets Admin <[email protected]> //STEP 2 RUN apt-get update && apt-get install -y openssh-server //STEP 3 RUN mkdir -p /var/run/sshd //STEP 4 #ADD sshd_config /etc/ssh/sshd_config COPY sshd_config /etc/ssh/sshd_config //STEP 5 ADD sample_tar.tar tar //STEP 6 ADD https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf /pdf/dummy.pdf //STEP 7 CMD /usr/sbin/sshd -D //STEP 8
ADD instruction
ADD instruction has some additional/ more features like local tar file extraction and remote URL support apart from copying of local files that is also supported by COPY instruction. To demonstrate these additional features let’s include the following instructions in the Dockerfile above.
ADD sample_tar.tar tar //STEP 6 ADD https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf /pdf/dummy.pdf //STEP 7
Though ADD and COPY looks similar, but these additional features are not immediately obvious.
To understand the concepts of ADD and COPY instructions first, let’s run the following docker build command to build docker image.
//docker build command $ docker build -t sneppets/ubuntu . Sending build context to Docker daemon 6.505MB Step 1/7 : FROM ubuntu ---> 1e4467b07108 Step 2/7 : MAINTAINER Sneppets Admin <[email protected]> ---> Running in e48c82fde51e Removing intermediate container e48c82fde51e ---> e4c4d4335b3e Step 3/7 : RUN apt-get update && apt-get install -y openssh-server ---> Running in 6b2126dbe615 Get:1 http://security.ubuntu.com/ubuntu focal-security InRelease [107 kB] Get:2 http://archive.ubuntu.com/ubuntu focal InRelease [265 kB] Get:3 http://security.ubuntu.com/ubuntu focal-security/multiverse amd64 Packages [1078 B] ---------- ------------ Step 4/7 : RUN mkdir -p /var/run/sshd ---> Running in 50db478f34ed Removing intermediate container 50db478f34ed ---> 8fc83f660edb Step 5/7 : COPY sshd_config /etc/ssh/sshd_config ---> 96561b9af5f2 Step 6/7 : ADD sample_tar.tar tar ---> fab2acf295d2 Step 7/7 : CMD /usr/sbin/sshd -D ---> Running in abd5c2ba1f29 Removing intermediate container abd5c2ba1f29 ---> 038f6060452f Successfully built 038f6060452f Successfully tagged sneppets/ubuntu:latest
Then run the following docker commands to understand the behavior and difference between ADD and COPY commands usage in Dockerfile.
//list docker images $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE sneppets/ubuntu latest 038f6060452f 11 seconds ago 222MB ubuntu latest 1e4467b07108 3 days ago 73.9MB //docker run command with bash command (instead of default command "/usr/sbin/sshd -D") to get the bash session //Then list directories to check what file system changes that ADD and COPY commands have done $ docker run --rm -it sneppets/ubuntu bash root@eac2811af92d:/# ls bin boot dev etc home lib lib32 lib64 libx32 media mnt opt pdf proc root run sbin srv sys tar tmp usr var //ADD command - tar file extraction root@eac2811af92d:/# cd tar root@eac2811af92d:/tar# ls sample_tar root@eac2811af92d:/tar# cd sample_tar/ root@eac2811af92d:/tar/sample_tar# ls readme.txt root@eac2811af92d:/tar/sample_tar# cat readme.txt Hello World ! //ADD command - Remote URL support root@eac2811af92d:/tar/sample_tar# cd .. root@eac2811af92d:/tar# cd .. root@eac2811af92d:/# cd pdf/ root@eac2811af92d:/pdf# ls dummy.pdf //COPY oommand - copy local files into the container root@c39ffa4b08eb:/tar/sample_tar# grep -i port /etc/ssh/sshd_config Port 2222 #GatewayPorts no root@c39ffa4b08eb:/tar/sample_tar# exit exit
Conclusion
Although ADD and COPY functionalities looked similar initially, but ADD supports additional features like tar file extraction and remote URL support which is not obvious immediately, generally speaking, COPY is preferred. That’s because it’s more transparent than ADD. Therefore, use ADD instruction in Dockerfile only if those additonal feature support is required.
Also See:
- Difference between CMD and ENTRYPOINT in Dockerfile ?
- How to run a command in a running docker container ?
- Ping inside the docker container from host
- Docker: Error response from daemon: OCI runtime create failed: container_linux.go:349
- List the directories inside the docker container
- Add new user to the Docker container using Dockerfile
- Docker images are storage location
- Difference between Docker Images, Containers and Registries
- Remove All Unused and Dangling Docker Images ?