Docker Tips #01 - Qual é a diferença entre ADD e COPY

DevOps

Docker Tips #01 - Qual é a diferença entre ADD e COPY

Marcos V. Leal

Marcos V. Leal

Junte-se a outros developers

Entre para nossa lista e receba conteúdos exclusivos e com prioridade

As instruções COPY e ADD são utilizadas em arquivos Dockerfile e possuem propósitos semelhantes.

Embora existam pequenas diferenças no escopo de sua aplicação, elas executam essencialmente a mesma operação: Copiar arquivos/diretórios de uma origem para um destino dentro da imagem.

Ok, então qual é a diferença entre Docker ADD e COPY? 🤔

Continue lendo…

Docker ADD

A instrução ADD está presente no Docker desde as suas primeiras versões.

O comando copia arquivos/diretórios para o destino especificado dentro do container, a sintaxe básica do ADD possui duas formas:

ADD [--chown=<user>:<group>] <src>... <dest> #1
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"] #2

Esse comando espera como argumentos a origem (<src>) e o destino (<dest>).

Se a origem for um diretório, o ADD irá copiar tudo dentro dele, incluindo os metadados do sistema de arquivos do SO1.

Outro ponto de atenção está no caminho, se contiver espaços em branco deverá ser utilizada a segunda forma da instrução.

Nota: O argumento --chown é compatível apenas com imagens usadas para criar contêineres Linux.

Por exemplo, se o arquivo estiver disponível localmente você poderá fazer algo como:

ADD coderarena.txt docs/

Para os casos em que você deseja copiar um diretório e todos os arquivos contidos nele, a instrução será:

ADD coderarena/sources/ /sources/

Note que existe uma diferença quando informamos o destino com uma / no início, podendo ser um caminho relativo ou absoluto em relação ao WORKDIR:

  1. <dest>/: especifica um caminho de destino relativo <WORKDIR>/relativeDir/.
  2. /<dest>/: especifica um caminho de destino absoluto /relativeDir/.

Além dos arquivos locais, o comando ADD também permite a cópia de arquivos externos por meio de uma URL informada no parâmetro de origem.

ADD https://coderarena.com.br/sources/test.txt /sources

Um recurso adicional é a possibilidade de copiar arquivos compactados e extraí-los automaticamente no destino.

Essa operação não se aplica a arquivos externos, ou seja, apenas arquivos salvos localmente podem ser descompactados pelo comando ADD.

Esse é um caso de uso válido, sendo utilizado pela imagem Alpine.

ADD coderarena.tar.gz docs/

Docker COPY

O comando ADD possui diversas funcionalidades que variam de acordo com o tipo da origem. Essa variedade trouxe uma série de problemas para o Docker, se comportando de forma extremamente imprevisível.

Sendo capaz de realizar extrações ao mesmo tempo em que copia arquivos compactados, tornou-se bastante comum casos em que apenas copiava quando você esperava por uma extração e extração quando queria apenas copiar.

Por essa razão, o Docker teve que introduzir um comando adicional para realizar a duplicação de conteúdo, haja visto que, não poderia simplesmente remover o comando problemático por questões de compatibilidade.

O COPY tem uma responsabilidade bastante simples: copiar os itens da origem, sem nenhuma manipulação automática, para o destino.

A instrução não é capaz de fazer a extração de arquivos compactados e, lida apenas com cópias de arquivos/diretórios presentes no host de build da imagem.

Docker COPY vs ADD

Com base em tudo o que aprendemos até aqui, está claro que você deve usar o COPY por padrão, além disso, o Docker possui um guia de boas práticas na escrita de Dockerfiles que desencoraja o uso do comando ADD.

Existe apenas uma situação na qual ele será indicado, ao extrair arquivos .tar locais para a sua imagem.

Para download e descompactação de arquivos externos, você pode substituir o ADD por curl ou wget no comando RUN do seu Dockerfile, abaixo um exemplo:

Ruim

ADD https://coderarena.com.br/sources/plugins.tar.xz /tmp/
RUN tar -xJf /tmp/plugins.tar.xz -C /tmp
RUN make -C /tmp all

Recomendado

RUN mkdir -p /tmp \
    && curl -SL https://coderarena.com.br/sources/plugins.tar.xz | tar -xJC /tmp \
    && make -C /tmp all

Sempre use COPY, é mais simples e explícito, exceto quando houver a necessidade de extração de um arquivo .tar local.

Referências:


  1. O termo “SO” é uma abreviação para Sistema Operacional.

Junte-se a outros Developers

Entre para nossa lista e receba conteúdos exclusivos e com prioridade

Você também pode gostar...

Gostou? Deixe seu comentário!

© 2023, Coder Arena. Todos os direitos reservados.