Skip to content

prefer-copy-over-add

COPY vs ADD in a Dockerfile: why COPY is the right default and the one case where ADD is actually the correct tool.

On this page

COPY and ADD both copy files into the image, but ADD carries hidden extra behavior: it auto-extracts local tar archives and can fetch remote URLs. Using ADD for ordinary file copies means every reader has to stop and ask which of those behaviors you meant. This rule flags ADD instructions that are doing plain copies.

What the rule catches

Dockerfile — ADD used as a plain copy
FROM node:22-slim
WORKDIR /app
ADD package.json ./
ADD src/ ./src/

Scanning this file reports:

⚠ WARN [docker-doctor/prefer-copy-over-add]
  ADD instruction used for regular files: 'package.json ./'. COPY is simpler and less prone to magic side effects.

Why it matters

The magic is the problem. ADD app.tar.gz /opt/ silently unpacks the archive — if you wanted the archive itself, you shipped a surprise instead. An ADD of a directory behaves like COPY, so the reader can't tell intent from the instruction. Docker's own best-practice guidance is blunt about it: use COPY unless you specifically need ADD's extraction. Explicit beats implicit in a file that builds your production artifact.

How to fix it

Use COPY instead of ADD unless you explicitly need auto-extraction of local compressed archives (tar, zip, etc.).

Dockerfile — COPY states exactly what happens
FROM node:22-slim
WORKDIR /app
COPY package.json ./
COPY src/ ./src/

The one legitimate ADD use: extracting a local tar archive into the image in a single instruction (ADD rootfs.tar.gz /), where the auto-extraction is the point. For remote URLs, ADD is flagged separately by no-add-remote — use RUN curl with checksum verification instead.

Rule details

  • Rule keydocker-doctor/prefer-copy-over-add
  • Category — Best Practices
  • Default severitywarning
  • Applies to — Dockerfiles

Explain this rule from the CLI:

npx @docker-doctor/cli@latest rules explain docker-doctor/prefer-copy-over-add

Change its severity — or turn it off — in your config file:

// docker-doctor.config.ts
export default {
  rules: {
    "docker-doctor/prefer-copy-over-add": "off",
  },
};

Severity affects the health score: error findings cost more points than warning, and info costs the least.