🐳 Docker Q11 / 20

What is the difference between COPY and ADD commands in Dockerfile?

AI-Powered Answer ✓ Answered

Both `COPY` and `ADD` are Dockerfile instructions used to transfer files from a source location (usually the Docker build context) into a Docker image. While they share a fundamental purpose, `ADD` offers additional functionalities that differentiate it from `COPY`.

COPY Command

The COPY instruction copies new files or directories from <src> and adds them to the filesystem of the image at the path <dest>. It is a straightforward and explicit command designed solely for copying local files and directories from the build context into the image.

It requires the source to be relative to the build context. If the source is a directory, its entire content, including filesystem metadata, is copied. If it's a file, it's copied directly. COPY is generally preferred for its transparency and predictability.

ADD Command

The ADD instruction also copies new files, directories, or remote file URLs from <src> and adds them to the filesystem of the image at the path <dest>. While it performs the basic copying function like COPY, ADD has two unique capabilities:

  • Tar Extraction: If the <src> is a tar archive (compressed or uncompressed like .tar, .tar.gz, .tgz, .bzip2, .xz), ADD will automatically decompress and extract its contents into the destination directory inside the image.
  • Remote URL Support: If the <src> is a URL, ADD will download the file from that URL and place it at the <dest> in the image. This feature is often discouraged due to caching issues and security concerns, with curl or wget typically preferred in a RUN instruction.

Key Differences and Use Cases

FeatureCOPYADD
Local File/Directory CopyingYesYes
URL Support (Download)NoYes (discouraged)
Automatic Tar ExtractionNoYes (if source is a tarball)
Transparency/PredictabilityHighLower (due to 'magic' features)
Best PracticePreferred for most local file transfersUse only when tar extraction is explicitly needed

When to use COPY

Always prefer COPY when you are simply moving local files or directories from your build context into the Docker image. It's more explicit, easier to understand, and prevents unintended behavior like tar extraction or accidental URL downloads. It's also less prone to unexpected caching issues compared to ADD's URL feature.

dockerfile
COPY . /app
COPY package.json /app/package.json

When to use ADD

Use ADD specifically when you need its unique capabilities: automatic tarball extraction into the image. For downloading files from URLs, it's generally recommended to use RUN combined with curl or wget for better control over caching, authentication, and error handling.

dockerfile
ADD source.tar.gz /app/