Header Ads

Compreendendo o contexto de compilação do Docker (por que você deve usar o Dockerignore)

O contexto de compilação do Docker se refere aos arquivos e diretórios que estarão disponíveis para o mecanismo do Docker quando você executar a compilação do docker. Qualquer coisa não incluída no contexto de construção não ficará acessível aos comandos em seu Dockerfile.

Você deve auditar o uso do docker build para manter seus contextos de construção pequenos. Incluir arquivos desnecessários acidentalmente pode resultar em um contexto de compilação excessivamente grande, o que levará a compilações mais longas.

Qual é o contexto de construção?

Aqui está um comando simples de construção do docker:

 compilação do docker. -t minha-imagem: mais recente 

Isso cria uma imagem Docker usando o Dockerfile encontrado em seu diretório de trabalho. A imagem resultante será marcada como minha-imagem: mais recente, embora esse detalhe não seja importante para este tutorial.

No seu Dockerfile, você provavelmente usará COPY para adicionar arquivos e pastas à sua imagem:

 DE httpd: última COPY index. html /usr/local/apache2/htdocs/index. html COPY css / / usr / local / apache2 / htdocs / css / 

Este exemplo copia o arquivo index. html e o diretório css para o seu contêiner. À primeira vista, parece que a instrução COPY simplesmente faz referência a um caminho que é resolvido em relação ao seu diretório de trabalho.

Esse não é bem o caso. O COPY só pode acessar recursos disponíveis no contexto de construção. Neste exemplo, o contexto de construção é o diretório de trabalho, portanto, os arquivos e pastas dentro dele estão disponíveis. Por padrão, o Docker usa o conteúdo do diretório passado para docker build como o contexto de construção.

Por que o contexto de construção é usado?

O contexto de construção é importante porque o Docker CLI e o Docker Engine podem não estar em execução na mesma máquina. Quando você executa o docker build, a CLI envia os arquivos e pastas para construir para o mecanismo Docker. Este conjunto de arquivos e pastas torna-se o contexto de construção.

Além disso, nem todo contexto de construção é tão simples quanto reutilizar seu diretório de trabalho. O Docker também oferece suporte a URLs de repositório Git como o caminho fornecido para a construção do docker. Nesse caso, o contexto de construção se torna o conteúdo do repositório especificado.

O padrão do contexto de compilação “ inclui todos os ” o comportamento é bom para muitos repositórios pequenos. Os problemas tornam-se aparentes quando você adiciona arquivos ao diretório de trabalho que não são usados ​​pelo Dockerfile. Recursos como binários pré-construídos, arquivos de documentação e bibliotecas de dependência serão incluídos no contexto de construção, embora sejam redundantes.

Incluir muitos recursos no contexto de construção pode prejudicar o desempenho. Você está copiando desnecessariamente arquivos que nunca serão usados. A lentidão será particularmente evidente se você estiver conectado a um daemon remoto do Docker ou se estiver usando um disco rígido mecânico lento. Você verá &’ enviando contexto de compilação para o daemon do Docker ” em seu shell enquanto a cópia é concluída.

O Docker tenta minimizar a cópia redundante por conta própria. O back-end de compilação BuildKit — usado desde o Docker 18.09 — adicionou suporte para transferências incrementais. Isso significa que o Docker geralmente só precisará copiar os arquivos adicionados ou alterados desde sua última compilação. Ele ainda irá copiar todo o lote na primeira compilação.

Excluindo recursos do contexto de compilação

Para resolver o desperdício de cópias para sempre, você deve dizer ao Docker o que ele pode omitir do contexto de construção. Vamos começar criando um Dockerfile:

 FROM node: mais recente WORKDIR / my-app COPY package. json package. json COPY package-lock. json package-lock. json COPY src /. RUN instalação npm 

Este Dockerfile simples pode ser usado por um aplicativo escrito em Node. js. Os programas Node. js usam o npm como gerenciador de pacotes. Os pacotes são instalados em uma pasta node_modules. Ao executar o npm install localmente, durante o desenvolvimento, os pacotes serão baixados para a pasta node_modules em seu diretório de trabalho.

O Dockerfile executa o próprio npm install para adquirir as dependências. Isso garante que a imagem seja totalmente independente. Não há necessidade de copiar na pasta localnode_modules, pois ela não é usada pelo Dockerfile.

Apesar disso, o Docker ainda incluirá a pasta node_modules no contexto de construção padrão. Para excluí-lo, crie um arquivo . dockerignore em seu diretório de trabalho. Este arquivo tem uma sintaxe semelhante a . gitignore.

 node_modules / 

Quaisquer caminhos listados em . dockerignore serão excluídos do contexto de construção. Você deve se certificar de que . dockerignore é mantido atualizado com as mudanças na estrutura do sistema de arquivos do seu projeto. Você pode reduzir substancialmente o tempo de cópia do contexto de construção do Docker verificando se apenas os caminhos relevantes (aqueles realmente usados ​​por seu Dockerfile) estão presentes no contexto de construção.

No caso do nosso exemplo, a pasta node_modules pode incluir milhares de arquivos se tivermos muitas dependências em nosso projeto. Copiá-los para o daemon do Docker como parte do contexto de construção pode levar vários segundos e seria uma operação inútil. O Dockerfile os ignora completamente, buscando suas próprias dependências por meio da instalação do npm.

Outros problemas de contexto de construção

Não usar . dockerignore pode introduzir outros problemas também. Um Dockerfile com esta linha é particularmente problemático:

[PRÉ] CÓPIA. / my-app

Isso copiará tudo em seu diretório de trabalho. Isso pode parecer uma boa ideia até que você perceba que seu histórico . git e todos os arquivos secretos também irão parar em seu contêiner.

Copiar um contexto de construção não filtrado também evita que o cache da camada do Docker funcione de maneira eficaz. Como algo em seu diretório de trabalho provavelmente mudará entre as compilações, o Docker precisaria executar a instrução COPY todas as vezes. Isso criaria uma nova camada — e novas camadas para quaisquer instruções subsequentes — mesmo se os ativos em que você está interessado não tenham mudado.

Compactando o contexto de construção

Você pode compactar o contexto de construção para melhorar ainda mais o desempenho da construção. Passe o sinalizador --compress para o docker build para aplicar a compactação gzip. A compactação ocorre antes de o contexto ser enviado ao daemon do Docker.

 compilação do docker. -t minha-imagem: mais recente --compress 

Isso pode melhorar o desempenho em alguns cenários. A compactação adiciona seus próprios overheads, embora — seu sistema agora precise compactar o contexto e o daemon receptor do Docker tenha que descompactá-lo. O uso da compactação pode ser mais lento do que copiar os arquivos originais, em algumas circunstâncias. Experimente cada uma de suas imagens para avaliar se você vê uma melhoria.

Conclusão

O contexto de construção do Docker define os arquivos que estarão disponíveis para cópia em seu Dockerfile. O contexto de construção é copiado para o daemon do Docker antes do início da construção.

O padrão dos contextos de construção inclui o conteúdo do diretório ou repositório Git que você passou para o docker build. Você pode omitir itens do contexto de construção criando um arquivo . dockerignore. Isso aumenta a eficiência, reduzindo a quantidade de dados redundantes passados ​​para o daemon do Docker.

Nenhum comentário