ADD
and COPY
are two similar Dockerfile
instructions which let you add content to your images at build time. Whereas COPY
is a straightforward source to destination copy, ADD
includes extra functionality for working with archives and remote URLs.
COPY
COPY
is the simpler of the two instructions. It accepts two arguments, a source and destination:
COPY example.txt /example/dir/example.txt
The source path will be copied from your Docker host into the container’s filesystem. The built image will include the copied file or directory at the specified destination path.
COPY
works with all files and directories but source paths are restricted to those within your active build context. The context is set when you run docker build
:
docker build . # OR docker build /path/to/context
The instruction automatically creates the destination directory in the container when it doesn’t already exist. If you include a trailing slash (/
), Docker treats the destination as a directory and will place the source file inside it.
You can use wildcards such as *.jpg
in the source path destination to match a set of files. These expressions will be parsed using the Go filepath
matcher.
Copied files have a UID and GID of 0 by default. This can be customized with the optional --chown
flag which accepts UIDs, GIDs, and names. It runs chown
on the copied files once they’re inside the container:
COPY --chown=my-user:my-group example.txt /example.txt
COPY
also supports a --from
flag. This modifies the source path to refer to another container image, instead of your local build context. It also works with multi-stage builds to pull in artifacts created by earlier build stages.
# Copies /usr/bin/composer from the composer:latest image COPY --from=composer:latest /usr/bin/composer /usr/bin/composer # Multi-stage build example # Stage 1: Copies example.scss from working directory into node:latest image # Stage 2: Copies example.css built in stage 1 into the final image (based on httpd:latest) FROM node:latest AS sass COPY example.scss . RUN npm install -g node-sass && node-sass example.scss example.css FROM httpd:latest COPY --from=sass /example.css example.css
The --from
flag must refer to a named stage that’s listed earlier in the Dockerfile
. When there’s no matching stage, Docker assumes you’re referencing an image instead. You’ll hit a build error if the image can’t be pulled.
ADD
ADD
has the same syntax as COPY
, accepting source and destination paths. There’s no support for --from
but you can use --chown
.
Unlike COPY
, ADD
is capable of downloading remote file URLs. Specifying a publicly accessible URL as the source path will download that file and add it to the container image. The destination path’s modified time (mtime
) will be set to the value of the Last-Modified
header in the download’s HTTP response.
ADD
can also extract tar archives, including archives compressed with gzip, bzip2, and xz. Specifying a compatible archive as the source path will unpack its contents into the specified container directory. The existing contents of the directory will be retained.
Archive detection is based on the actual file contents, not the filename or extension. You can use any genuine archive file without naming it .tar
, .tar.gz
or .tar.xz
.
The ability to automatically extract archives simplifies adding software packages distributed as tar files to your container images. Supplying a tar path to COPY
would copy the compressed archive file as-is, not its contents. You’d need to use a RUN
instruction to manually decompress the file.
The behaviors around COPY
apply to ADD
to. Except for remote URLs, source paths must exist in your build context. The container’s destination path will be automatically created when it doesn’t exist using Docker’s rules for path resolution.
Summary
COPY
and ADD
are two closely related but distinctly different instructions you can use when writing a Dockerfile
. As their feature sets overlap, you might be wondering which is the “best” to use by default.
According to Docker’s own best practices guide, you should reach for COPY
unless you need the extra capabilities of ADD
. ADD
is an opaque operation that adds magic to the copying process.
Only using ADD
when it’s actually needed helps to communicate your intentions. Otherwise, you risk getting team members into the habit of using ADD
which could have disastrous consequences. An unintentional ADD my-archive.tar .
instead of COPY my-archive.tar
could cause confusion and broken builds when the archive’s contents show up in your container, instead of the archive itself.
You should also carefully consider when it’s appropriate to use ADD
with remote URLs. It can be more efficient to use curl
or wget
with a RUN
instruction as this helps facilitate image layer caching. An ADD
instruction will always invalidate the cache for all following build stages when the file at a remote URL changes.
Where possible, it’s good practice to delete copied files after they’ve been used. If you’re downloading or extracting a software installer, deleting the one-time binary after you’ve run it will help to slim down your final image.
- › You Can Wash Your Motherboard In a Dishwasher (But You Probably Shouldn’t)
- › Bing Chat AI Now Has Better Search and Higher Limits
- › ChatGPT Network Error: 7 Fixes to Try
- › Fix: “Message Has Not Been Downloaded From the Server” on iPhone
- › How to Know If Someone Restricted You on Instagram
- › How to Enable Dark Mode in Real Life