Docker COPY: Dockerfile best practices
Docker has two similar Dockerfile instructions,
ADD, which are both used to include files in an image. This article will explain why it is best practice to use
COPY rather than
ADD, unless you want to auto-extract a local
tar file into an image.
Best practices for using COPY
This Dockerfile instruction copies one or many local files or folders into the destination within your Docker image.
COPY <source>... <destination>
COPY ["<source>",... "<destination>"](this form is required for paths containing whitespace)
An example Dockerfile that uses COPY
This is how you would use
COPY in a Dockerfile for a Ruby app.
COPY Gemfile Gemfile.lock ./
RUN bundle install
COPY . .
The Docker instruction
WORKDIR defines a working directory for the
ADDs instructions that follow it.
When you use
COPY it will copy the files from the local source, in this case
. meaning the files in the current directory, to the location defined by
WORKDIR. In the above example, the second
. refers to the current directory in the working directory within the image.
Best practices for creating image layers with COPY
Docker recommends using
COPY to create image layers in a way that keeps different file contexts in separate image layers. This means rebuilding the image is efficient. The files least likely to be changed should be in lower layers, while the files most likely to change should be added last.
If you have multiple
Dockerfilesteps that use different files from your context,
COPYthem individually, rather than all at once. This ensures that each step’s build cache is only invalidated (forcing the step to be re-run) if the specifically required files change.
— Best practices for writing Dockerfiles
This principle is demonstrated in the Dockerfile example above. By copying the Gemfiles followed by
RUN bundle install , an image layer is created with the installed Ruby Gems, which can be cached. The last two Docker instructions copy the app’s files into the image and set the default command using
This means if you change any of the app’s files, you can rebuild the Docker image using the cached parent and intermediate layers. This is much more efficient than building all of them from scratch.
Why you should not use ADD
ADD instruction has similar syntax to
COPY. As well as copying local files and directories into the destination within the Docker image, it has some additional features.
ADD <source>... <destination>
ADD ["<source>",... "<destination>"](this form is required for paths containing whitespace)
However, Docker’s official guide to Dockerfile best practices states that
COPY is the preferred instruction over
ADD in most uses.
COPYare functionally similar, generally speaking,
COPYis preferred. That’s because it’s more transparent than
COPYonly supports the basic copying of local files into the container, while
ADDhas some features (like local-only tar extraction and remote URL support) that are not immediately obvious. Consequently, the best use for
ADDis local tar file auto-extraction into the image, as in
ADD rootfs.tar.xz /— Best practices for writing Dockerfiles
ADD‘s additional features is that it can copy files from a URL, but Docker advises against using it for this purpose.
Best practices for copying files from a URL
ADD’s source is a URL, it will download and copy the file into the destination within the Docker image. Docker suggests that it is often not efficient to copy from a URL using
ADD, and it is best practice to use other strategies to include the required remote files.
Because image size matters, using
ADDto fetch packages from remote URLs is strongly discouraged; you should use
wgetinstead. That way you can delete the files you no longer need after they’ve been extracted and you don’t have to add another layer in your image.
— Dockerfile Best Practices
For example, you should avoid doing things like:
ADD http://example.com/big.tar.xz /usr/src/things/
RUN tar -xJf /usr/src/things/big.tar.xz -C /usr/src/things
RUN make -C /usr/src/things all
And instead, do something like:
RUN mkdir -p /usr/src/things \
&& curl -SL http://example.com/big.tar.xz \
| tar -xJC /usr/src/things \
&& make -C /usr/src/things all
When you could use ADD
<source> is a local
tar archive in a recognized compression format, then it is automatically unpacked as a directory into the Docker image. For example:
ADD rootfs.tar.xz /. This is the main recommended use of
COPY in Dockerfiles.
For other items (files, directories) that do not require
ADD’s tar auto-extraction capability, you should always use
Find out more
The official Dockerfile reference goes into further detail on
ADD and other Dockerfile instructions.
When writing your Dockerfiles, Docker’s Best practices for writing Dockerfiles covers many more tips for how to structure your Dockerfiles, images, and containers efficiently.
I own and have found the following books helpful when learning Docker, containerisation, and shell commands. These contain Amazon affiliate links. If you click through & make a purchase, I will earn a commission at no additional cost to you.
- Docker Deep Dive by Nigel Poulton — From the basics to more in-depth explanation of how to use Docker.
- The Kubernetes Book by Nigel Poulton — Learn how to configure, deploy and manage containerized applications at scale.
- Bash Pocket Reference by Arnold Robbins is an easy to read reference for learning and using Bash.
- The Linux Command Line by William E. Shotts Jr is a more detailed overview of Bash and the command line for Linux and Mac.