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