# ADD or COPY in Dockerfile

### Concept & fundamental

`ADD` and `COPY` are functionally similar

* `ADD` has some features like local-only tar extraction and **remote URL support**

  Consequently, the best use for `ADD` is local tar file auto-extraction into the image, as in&#x20;

  ```
   ADD rootfs.tar.xz /.
  ```
* `COPY` **only** supports the basic copying of local files into the container

  &#x20;With multiple steps in Dockerfile, that use **different files** from your context  --> `COPY` them individually, rather than all at once. This will ensure that each step’s build cache is only invalidated (forcing the step to be re-run) if the specifically required files change.

  ```
   COPY requirements.txt /tmp/
   RUN pip install --requirement /tmp/requirements.txt
   COPY . /tmp/
  ```

  &#x20;Results in fewer cache invalidations for the `RUN` step, than if you put the `COPY . /tmp/` before it.

Because image size matters, using `ADD` to fetch packages from remote URLs is **strongly discouraged**; you **should use** `curl` **or** `wget` instead. That way you can delete the files you no longer need after they’ve been extracted and you won’t have to add another layer in your image.

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
```

For other items (files, directories) that do not require `ADD`’s tar auto-extraction capability

You should always use `COPY`.

### Reference:

1. <https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/#add-or-copy>
2. <https://stackoverflow.com/questions/24958140/what-is-the-difference-between-the-copy-and-add-commands-in-a-dockerfile>
