docker tutorials

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.


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 /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 /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 focal-security InRelease [107 kB]
Get:2 focal InRelease [265 kB]
Get:3 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
root@eac2811af92d:/tar# cd sample_tar/
root@eac2811af92d:/tar/sample_tar# ls
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

//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


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:


Notify of

Inline Feedbacks
View all comments