Sobes.tech
Middle

Quais são as melhores práticas para usar as instruções ADD e COPY no Docker?

sobes.tech IA

Resposta da IA

Existem várias melhores práticas para as instruções ADD e COPY no Docker, destinadas a melhorar a segurança, transparência e eficiência na construção de imagens.

A principal diferença entre ADD e COPY:

  • COPY simplesmente copia arquivos e diretórios desde a fonte especificada no host para o destino na imagem. A fonte deve ser um arquivo ou diretório local.
  • ADD tem capacidades mais amplas: pode copiar arquivos e diretórios locais, bem como extrair arquivos (tar, gzip, bzip2) e obter arquivos de URLs.

Melhores práticas:

  1. Prefira COPY em vez de ADD: Na maioria dos casos, COPY é suficiente. É mais transparente, pois apenas copia arquivos locais. Usar ADD para extrair arquivos ou fazer download de URLs pode ser menos previsível e aumentar a complexidade da construção.

  2. Use COPY para arquivos locais: Se precisar copiar arquivos do contexto de construção para a imagem, sempre use COPY.

    # Em vez de ADD . /app
    COPY . /app 
    
  3. Tenha cuidado com URLs em ADD: Usar ADD com URL pode levar a instabilidade na construção se o recurso remoto não estiver disponível. Além disso, pode ser menos seguro, pois depende de uma fonte externa. É preferível usar curl ou wget em uma camada separada (RUN) para baixar recursos via URL, o que dá mais controle e permite verificar somas de verificação.

    # Em vez de ADD http://example.com/file.tar.gz /tmp/
    RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/* \
        && curl -fsSL http://example.com/file.tar.gz -o /tmp/file.tar.gz \
        && tar -xzf /tmp/file.tar.gz -C /app \
        && rm /tmp/file.tar.gz
    
  4. Extraia arquivos em uma camada separada ao usar ADD: Se deve usar ADD para extrair um arquivo (cenário menos comum), certifique-se de fazer isso em uma camada separada. No entanto, como mencionado anteriormente, geralmente é melhor fazer a extração explicitamente com RUN.

  5. Copie apenas os arquivos necessários: Não copie todo o contexto de construção (COPY . /app) se contiver arquivos desnecessários (código fonte, dados de teste, diretórios ocultos, etc.). Use .dockerignore para excluir esses arquivos. Isso reduz o tamanho da imagem e acelera a construção ao diminuir a quantidade de dados transferidos para o daemon do Docker.

    Exemplo de .dockerignore:

    .git
    node_modules
    *.log
    tmp/
    
    # Copie apenas os arquivos necessários após aplicar `.dockerignore`
    COPY . /app
    
  6. Use caminhos absolutos para destinos: Sempre indique caminhos absolutos na imagem (/app, /usr/local/bin, etc.). Isso torna o Dockerfile mais compreensível e previsível, evitando incertezas quanto ao diretório de trabalho atual (WORKDIR).

    # Sempre indique caminhos absolutos para o destino
    COPY src /app/src
    
  7. Varia a ordem dependendo da frequência de alterações: Coloque as instruções COPY ou ADD para arquivos que mudam menos frequentemente (por exemplo, arquivos de dependências como package.json, requirements.txt) no topo do Dockerfile, e as instruções para arquivos que mudam mais frequentemente (código fonte da aplicação) na parte inferior. Isso permite que o Docker aproveite eficientemente o cache de camadas.

    # Arquivos de dependências (mudam menos)
    COPY requirements.txt /app/
    RUN pip install --no-cache-dir -r requirements.txt
    
    # Código fonte da aplicação (muda mais)
    COPY . /app/ 
    

Tabela resumo:

Instrução Descrição Uso recomendado O que evitar
COPY Copia arquivos/diretórios locais Copiar arquivos e diretórios locais para a imagem. Usar se precisar extrair arquivos ou fazer download via URL.
ADD Copia arquivos/diretórios locais, extrai arquivos, faz download via URL Uso para extração automática de arquivos (pouco frequente). Usar para copiar arquivos locais (prefira COPY). Usar para download via URL.

Seguindo essas práticas leva à criação de imagens Docker mais confiáveis, seguras e eficientes.