Dockerfile: Why You Should Use COPY Instead of ADD

This page describes a highlighted problem produced by the Docker and Kubernetes Security scanner plugin.

You could find more details on the internal page: Cloud (IaC) Security plugin

If this project has been helpful to you, please consider giving it a ⭐ on GitHub to help others discover it.

Problem

Using ADD when you only need a plain file copy makes a Dockerfile less predictable and harder to review. In most build stages, COPY is the safer and clearer default.

Description

At first glance, ADD and COPY look similar because both place files into an image. The difference is that ADD has extra behavior: it can unpack local archives and it can fetch content from remote URLs. Those side effects are convenient in rare cases, but they increase ambiguity in day-to-day Dockerfiles.

When a reviewer sees COPY ./app /app, the intention is obvious: move local build context files into the image. With ADD, the reader has to remember additional semantics and consider edge cases like auto-extraction and remote retrieval. That extra cognitive load slows reviews and makes mistakes more likely, especially in large teams where many people touch the same image definitions.

Security and reproducibility are also important. If a build process depends on remote content, results can change over time without a Dockerfile change. This weakens traceability, cache predictability, and incident response. Explicitly using COPY for local assets and a separate verified download step for remote assets creates a more controlled and auditable build pipeline.

Why this matters

  • Reproducibility: predictable builds are easier to debug and promote across environments.
  • Security: explicit download and checksum verification is safer than implicit remote behavior.
  • Reviewability: intent is clearer when file copy and download logic are separated.
  • Caching: deterministic layers produce more stable build cache behavior in CI.

Solution

Use COPY by default for local files and directories. If you need remote files, download them explicitly in a RUN step and verify integrity (for example, checksum or signature) before use. This keeps build behavior intentional and easy to audit.

When ADD is acceptable

ADD can still be valid in narrow cases, such as controlled local archive extraction where the behavior is clearly documented and tested. Even then, many teams prefer explicit extraction commands because they are easier to reason about during security reviews.

Problematic code

FROM ubuntu:20.04
USER nobody
ADD ./app /app

Verified code

FROM ubuntu:20.04
USER nobody
COPY ./app /app

Rule of thumb: if your intent is only to copy local files, use COPY. Keep ADD as an exception, not a default.