# ADD

A instrução `ADD` em um Dockerfile é utilizada para copiar arquivos e diretórios do sistema de arquivos local (host) para o sistema de arquivos do contêiner durante a construção da imagem. Ela é semelhante à instrução `COPY`, mas oferece funcionalidades adicionais, como a capacidade de descompactar arquivos automaticamente e de baixar arquivos de URLs remotas.

#### Sintaxe Básica

```dockerfile
ADD [opções] <origem>... <destino>
```

* **`<origem>`**: Especifica o caminho do arquivo ou diretório no sistema de arquivos local que será copiado. Pode incluir arquivos específicos ou usar padrões glob (como `*.txt`). Se `<origem>` for uma URL, o conteúdo será baixado e colocado no `<destino>`.
* **`<destino>`**: Especifica o caminho no contêiner onde o conteúdo será copiado ou descompactado. Esse caminho pode ser um diretório existente ou um novo diretório que será criado automaticamente.

#### Funcionalidades Adicionais do `ADD`

* **Descompactação Automática**: Se o arquivo de origem for um arquivo comprimido no formato `.tar`, `.gz`, `.bz2`, `.xz`, `.zip`, ele será automaticamente descompactado no destino.
* **Download de URLs**: O `ADD` pode baixar arquivos de URLs remotas e colocá-los no contêiner. No entanto, esta prática não é recomendada devido a potenciais problemas de segurança e previsibilidade.

#### Exemplos de Uso

**Copiar Arquivo Simples**

```dockerfile
FROM nginx:alpine
ADD index.html /usr/share/nginx/html/
```

Neste exemplo, o arquivo `index.html` do sistema de arquivos local é copiado para o diretório `/usr/share/nginx/html/` no contêiner.

**Copiar e Descompactar Arquivo**

```dockerfile
FROM busybox
ADD files.tar.gz /usr/src/app/
```

Aqui, o arquivo `files.tar.gz` é descompactado no diretório `/usr/src/app/` dentro do contêiner. Se `files.tar.gz` contiver vários arquivos e diretórios, eles serão extraídos para `/usr/src/app/`.

**Baixar Arquivo de URL**

```dockerfile
FROM alpine:latest
ADD https://example.com/file.txt /root/file.txt
```

Neste exemplo, o arquivo `file.txt` é baixado da URL `https://example.com/file.txt` e colocado no diretório `/root/` dentro do contêiner.

#### Considerações e Boas Práticas

* **Segurança**: Evite usar `ADD` para baixar arquivos de URLs externas, pois isso pode introduzir vulnerabilidades ou tornar a construção da imagem imprevisível devido a mudanças no conteúdo remoto. Em vez disso, prefira baixar arquivos manualmente e incluí-los com `COPY`.
* **Descompressão Automática**: Embora a descompressão automática possa ser conveniente, ela pode resultar em comportamentos inesperados. Utilize `ADD` para essa função somente se tiver certeza do conteúdo e do formato do arquivo.
* **Ordem de `ADD`**: Assim como `COPY`, o `ADD` utiliza cache para otimizar a construção das imagens. Mudar o conteúdo copiado ou baixado pode invalidar o cache, forçando a reexecução das instruções subsequentes.
* **Preferir `COPY`**: Se você não precisar das funcionalidades extras de `ADD` (como descompressão ou download de arquivos), prefira `COPY`, que é mais simples e explícito em seu propósito.

#### Exemplos Avançados

**Usando `.dockerignore` com `ADD`**

Assim como com `COPY`, você pode usar um arquivo `.dockerignore` para excluir determinados arquivos ou diretórios ao usar `ADD`.

**Estrutura do Projeto:**

```plaintext
.
├── Dockerfile
├── .dockerignore
└── data/
    ├── data.csv
    └── secret.txt
```

**.dockerignore:**

```plaintext
data/secret.txt
```

**Dockerfile:**

```dockerfile
FROM python:3.10
ADD ./data /app/data
```

Neste caso, o arquivo `secret.txt` será ignorado durante a operação de `ADD`, mesmo que esteja dentro do diretório `data`.

#### Diferença entre `ADD` e `COPY`

* **`COPY`**: Usa-se para copiar arquivos ou diretórios locais para o contêiner. Simples e direto, sem nenhuma funcionalidade adicional.
* **`ADD`**: Pode copiar arquivos locais, descompactar arquivos automaticamente e baixar arquivos de URLs remotas.

#### Quando Usar `ADD`

* **Descompactação de Arquivos**: Use `ADD` se precisar descompactar um arquivo tar, gzip, ou outro formato suportado durante a cópia.
* **Download de Arquivos Remotos**: Embora possível, usar `ADD` para baixar arquivos de URLs remotas não é uma prática recomendada. Prefira o uso de ferramentas como `curl` ou `wget` em um comando `RUN` para esse propósito.

#### Resumo

* **`ADD`** oferece mais funcionalidades que `COPY`, mas deve ser usado com cautela.
* Prefira `COPY` quando possível, e use `ADD` apenas quando precisar de suas funcionalidades extras, como descompressão automática ou downloads de URLs.
* Tenha atenção à segurança e previsibilidade ao usar `ADD`.

## Laboratório

### Url

```docker
FROM ubuntu
RUN apt update && apt install curl --yes
WORKDIR /app
ADD https://www.google.com pagina.html
```

```bash
$ docker build -t ubuntu-curl .
[+] Building 0.4s (9/9) FINISHED                                    docker:default
 => [internal] load build definition from Dockerfile                          0.0s
 => => transferring dockerfile: 142B                                          0.0s
 => [internal] load metadata for docker.io/library/ubuntu:latest              0.0s
 => [internal] load .dockerignore                                             0.0s
 => => transferring context: 2B                                               0.0s
 => [1/4] FROM docker.io/library/ubuntu:latest                                0.0s
 => [4/4] ADD https://www.google.com pagina.html                              0.2s
 => CACHED [2/4] RUN apt update && apt install curl --yes                     0.0s
 => CACHED [3/4] WORKDIR /app                                                 0.0s
 => [4/4] ADD https://www.google.com pagina.html                              0.0s
 => exporting to image                                                        0.0s
 => => exporting layers                                                       0.0s
 => => writing image sha256:9caa72d296109dd1ca29417bd0c03f9b241e4e6c1cef7fc9  0.0s
 => => naming to docker.io/library/ubuntu-curl                                0.0s
$ docker container run -it ubuntu-curl /bin/bash
root@d133be83f032:/app# ls
pagina.html
root@d133be83f032:/app# cat pagina.html
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" ...
```

> Não faz uso de cache

### Arquivo compactado

```bash
$ mkdir arquivos
$ cd arquivos/
$ echo "Arquivo teste" > arquivo.txt
$ echo "Arquivo teste" > teste.txt
$ ls
arquivo.txt teste.txt
$ cd ..
$ tar -zvcf teste.tar.gz arquivos/
$ ls
teste.tar.gz
```

```docker
FROM ubuntu
RUN apt update && apt install curl --yes
WORKDIR /app
ADD https://www.google.com pagina.html
ADD teste.tar.gz ./
```

```bash
$ docker build -t ubuntu-curl .
[+] Building 0.4s (11/11) FINISHED                                  docker:default
 => [internal] load build definition from Dockerfile                          0.0s
 => => transferring dockerfile: 161B                                          0.0s
 => [internal] load metadata for docker.io/library/ubuntu:latest              0.0s
 => [internal] load .dockerignore                                             0.0s
 => => transferring context: 2B                                               0.0s
 => [1/5] FROM docker.io/library/ubuntu:latest                                0.0s
 => [4/5] ADD https://www.google.com pagina.html                              0.2s
 => [internal] load build context                                             0.0s
 => => transferring context: 235B                                             0.0s
 => CACHED [2/5] RUN apt update && apt install curl --yes                     0.0s
 => CACHED [3/5] WORKDIR /app                                                 0.0s
 => [4/5] ADD https://www.google.com pagina.html                              0.0s
 => [5/5] ADD teste.tar.gz ./                                                 0.0s
 => exporting to image                                                        0.1s
 => => exporting layers                                                       0.0s
 => => writing image sha256:d07b8ff06d4001fc190b473a64baa25168db0df7ba8f8b82  0.0s
 => => naming to docker.io/library/ubuntu-curl                                0.0s
$ docker container run -it ubuntu-curl /bin/bash
root@b7c8833677d7:/app# ls
arquivos  pagina.html
root@b7c8833677d7:/app# cd arquivos/
root@b7c8833677d7:/app/arquivos# ls
arquivo.txt  teste.txt
```

> **Boa prática**: preferir o COPY ao ADD a não ser que seja necessário trabalhar com arquivo remoto ou compactado
