COPY and ADD are both Dockerfile instructions that serve similar purposes. They let you copy files from a specific location into a Docker image.
Purpose
Copy the files form source to destination. COPY and ADD both has two forms.
ADD [–chown=<user>:<group>] <src>… <dest>
ADD [–chown=<user>:<group>] [“<src>”,… “<dest>”]
This latter form is required for paths containing whitespace. And COPY
COPY [–chown=<user>:<group>] <src>… <dest>
COPY [–chown=<user>:<group>] [“<src>”,… “<dest>”]
This latter form is required for paths containing whitespace. Create tow sample files.
$ mkdir copy_add
$ cd copy_add
$ echo “this is sample file” > sample.txt
$ echo “this is example file” > example.txt Write a Dockerfile using COPY and ADD FROM busybox
COPY sample.txt /tmp ADD example.txt /tmp CMD [“sh”]
Build the docker image
$ docker build -t copyaddtest . Run as a container
$ docker run -it –name copyaddtest copyaddtest sh Test it
# ls -ltr /tmp
Here as we seen COPY and ADD we can use same purpose but there are couple of difference, lets discuss
Difference
COPY
The COPY instruction copies files or directories into the Docker image. It takes a src and destination as arguments.
Source can be absolute or relative from current WORKDIR or wild cards. Destination path can be absolute or relative to current WORKDIR.
For Example:
COPY ./requirements.txt /app/requirements.txt COPY package.json package-lock.json /app COPY package*.json /app
COPY . /app
ADD
The ADD instruction copies files, directories, remote file or tar archive into the Docker image.
It takes a src and destination as arguments. Source can be files and directories.
Source can be a URL. The ADD instruction will download the file from the URL and save it to the destination. We don’t need to use curl or wget to download a file.
Source can be a local tar/zip archive. The ADD instruction will automatically extract it to the destination. We don’t need to run unarchive commands manually.
Use ADD when you want download a file from a URL or extract local archive file. For Example:
For Example:
ADD ./example.tar.gz /tmp/
ADD https://bootstrap.pypa.io/get-pip.py /get-pip.py /get-pip.py ADD example.txt /tmp/
ADD https://mirrors.estointernet.in/apache/tomcat/tomcat-8/v8.5.58/bin/apache-tomcat- 8.5.58.tar.gz /tmp/
$ tar -cvzf example.tar.gz ./
Use ADD
FROM busybox
ADD example.tar.gz /tmp/ CMD [“sh”]
Build the image
$ docker build -t copyaddtest:v1 . Run the container
$ docker run -it –name copyaddtest1 copyaddtest:v1 sh Test it
Use COPY
Write a sample Dockerfile FROM busybox
COPY example.tar.gz /tmp/ CMD [“sh”]
Let’s build the image
$ docker build -t copyaddtest:v2 . Let’s run the container
$ docker run -it –name copyaddtest2 copyaddtest:v2 sh Let’s test it
Conclusion: here ADD command its copied and extracted where COPY only do copy the files. If you want to extract the tar file need to add one more extra command in Dockerfile.
Let’s see… FROM busybox
COPY example.tar.gz /tmp/ WORKDIR /tmp/
RUN tar -xvzf example.tar.gz . CMD [“sh”]
Build the docker image
$ docker build -t copyaddtest:v3 . Run the docker container
$ docker run -it –name copyaddtest3 copyaddtest:v3 sh Let’s test it
FROM URL
FROM busybox WORKDIR /tmp/
ADD https://mirrors.estointernet.in/apache/tomcat/tomcat-8/v8.5.58/bin/apache-tomcat- 8.5.58.tar.gz /tmp/
CMD [“sh”]
Build the image
$ docker build -t test:v10 .
Run the container
$ docker run -it –name test10 test:v10 sh Test the container
If you want extract tar file you need add RUN tar command. Let’s see FROM busybox
WORKDIR /tmp/
ADD https://mirrors.estointernet.in/apache/tomcat/tomcat-8/v8.5.58/bin/apache-tomcat- 8.5.58.tar.gz /tmp/
RUN tar -xvzf apache-tomcat-8.5.58.tar.gz CMD [“sh”]
Build the image
$ docker build -t test:v11 . Run the container
$ docker run -it –name test11 test:v11 sh Test the container
Best practices using ADD and Copy
Instead of using add to download form remote url use curl or wget and use && multiple commands to execute.
FROM ubuntu WORKDIR /tmp/
RUN apt-get update && apt-get install wget -y && wget https://mirrors.estointernet.in/apache/tomcat/tomcat-8/v8.5.58/bin/apache-tomcat-8.5.58.tar.gz && tar xvf apache-tomcat-8.5.58.tar.gz && rm -rf apache-tomcat-8.5.58.tar.gz
CMD [“sh”]
Build the image
$ docker build -t test:v12 .
Run the container
docker run -it –name test12 test:v12 bash test the container
Finally one more :
One more noteworthy difference between ADD and COPY is that COPY has the — from=<name|index> flag that lets you copy files from a previous build stage in a multi-stage build. ADD does not have this option.This is another reason to use COPY as your preferred option.