construir contexto para imagem docker muito grande


142

Criei alguns diretórios diferentes na minha máquina host enquanto tento aprender sobre o Docker apenas para manter meus arquivos docker organizados. Meu Dockerfile que acabei de executar fica assim:

FROM crystal/centos
MAINTAINER crystal

ADD ./rpms/test.rpm ./rpms/ 
RUN yum -y --nogpgcheck localinstall /rpms/test.rpm 

Minha rpm real é de apenas 1 GB. Mas quando tento fazer sudo docker build -t="crystal/test" ., recebo o contexto de construção para o daemon Docker de 3,5 GB. Existe alguma outra coisa que eu desconheço enquanto você continua criando imagens do Docker? Minha memória está se acumulando à medida que construo mais imagens em meus outros diretórios na minha máquina host?


2
O contexto de construção são todos os arquivos / diretórios no diretório atual.
Nabin

Mantenha apenas os arquivos necessários para a construção neste diretório. Ou seja, o Dockerfile e quaisquer arquivos / diretórios locais copiados / adicionados à imagem de compilação no Dockerfile. Além disso, faça uso de.dockerignore
Vishrant

Respostas:


266

O cliente do Docker envia todo o "contexto de construção" para o daemon do Docker. Esse contexto de construção (por padrão) é o diretório inteiro Dockerfileem que está (portanto, a rpmsárvore inteira ).

Você pode configurar um .dockerignorearquivo para que o Docker ignore alguns arquivos. Você pode experimentar isso.

Como alternativa, você pode mover sua rpmspasta um nível de diretório acima do seu Dockerfile, e apenas ligar novamente test.rpmpara o Dockerfilediretório da pasta .


Como muitos usuários apontaram nos comentários, é necessário adicionar a .gitpasta à.dockerignore qual foi a causa de uma diferença de 150 MB -> 5 GB no meu caso.


4
Infelizmente, parece que a ligação simbólica não é possível nesse caso, pois o ADDcomando não segue os links sym durante uma compilação. Veja: github.com/docker/docker/issues/1676
JimmidyJoo

5
salva-vidas! Rails desenvolvedores: se esqueça de adicionar tmp loga .dockerignore+ outros entes personalizados
equivalent8

7
não se esqueça de adicionar pasta .git para .dockerignore arquivo (supondo que você está usando git)
DsnCode

8
Sim, a .gitpasta está incluída por padrão - isso definitivamente me chamou a atenção.
Paul Suart

1
Qual é o "contexto de construção" exatamente? Tentei procurar esses arquivos usando o comando docker build RUN, mas não vejo os arquivos na minha pasta Dockerfile dentro do sistema de arquivos docker (durante o tempo de construção.) Alguém pode me dar um exemplo simples de como o contexto de construção é útil?
Patrick

52

Atualização 2019

A partir do Docker v18.06, há uma opção para usar um novo construtor de imagens chamado Build Kit .

Ele vem com o Docker, não é necessário instalar nada. É compatível com a Dockerfilesintaxe, não há necessidade de alterar o Dockerfile.

Legado Docker Build vs Novo Docker BuildKit

Aqui está um exemplo de criação de uma imagem com um enorme arquivo não utilizado no diretório de construção:

Construção herdada do Docker:

$ time docker image build --no-cache .
Sending build context to Docker daemon  4.315GB
[...]
Successfully built c9ec5d33e12e

real    0m51.035s
user    0m7.189s
sys 0m10.712s

Novo BuildKit do Docker:

$ time DOCKER_BUILDKIT=1 docker image build --no-cache .
[+] Building 0.1s (5/5) FINISHED                                                
 => [internal] load build definition from Dockerfile                       0.0s
 => => transferring dockerfile: 37B                                        0.0s
 => [internal] load .dockerignore                                          0.0s
 => => transferring context: 2B                                            0.0s
[...]
 => => writing image sha256:ba5bca3a525ac97573b2e1d3cb936ad50cf8129eedfa9  0.0s

real    0m0.166s
user    0m0.034s
sys 0m0.026s

A única mudança é a DOCKER_BUILDKIT=1variável de ambiente, a diferença no tempo é enorme.

.dockerignore Arquivo

Observe que o .dockerignorearquivo ainda é válido e útil. Alguns Dockerfilecomandos como COPY . .ainda levarão em conta as .dockerignoreregras. Mas os arquivos laterais no diretório de construção (não mencionados no Dockerfile) não estão mais sendo copiados como um "contexto de construção" pelo BuildKit.


1
É importante observar que atualmente não há suporte para DOCKER_BUILDKIT para contêineres do Windows. (Somente Linux, listado sob limitações: docs.docker.com/develop/develop-images/build_enhancements )
Vaccano

18

Corrigi-o movendo meu Dockerfile e docker-compose.yml para uma subpasta e funcionou muito bem. Aparentemente, o docker envia a pasta atual para o daemon e minha pasta foi de 9 GB.


4
Este método fornece o caminho proibido: fora do erro do contexto de construção, se um arquivo de um diretório pai estiver sendo copiado, alguma solução para isso?
Kitwradr

8

Se você tiver um .dockerignorearquivo e o contexto de construção ainda for grande, poderá verificar o que está sendo enviado para o contexto de construção do Docker usando o Silver Searcher :

ag --path-to-ignore .dockerignore --files-with-matches

Observe que alguns **padrões podem não funcionar corretamente.

Veja esta edição do Github para comentários adicionais: https://github.com/moby/moby/issues/16056


4

No meu caso, foi quando eu executo com -fargumentos errados - sem o caminho para o diretório em que estava localizado o Dockerfile

docker build --no-cache -t nginx5 -f /home/DF/Dockerfile /home/DF/ - certo

docker build --no-cache -t nginx5 -f /home/DF/Dockerfile - errado


1

Se você deseja ter controle total do seu contexto de construção, também poderá construir o contêiner completamente, sem nenhum contexto e COPYdados relevantes no contêiner posteriormente.

docker build - < Dockerfile

Uma desvantagem disso seria que, com essa abordagem, você pode apenas ADDno arquivo docker referenciar uma URL remota, e não os arquivos do host local.

Consulte https://docs.docker.com/engine/reference/commandline/build/#build-with--


0

Eu tive o mesmo problema que o FreeStyler. No entanto, eu estava construindo a partir de um diretório acima do meu contexto. Portanto, os argumentos -f estavam corretos, o contexto estava incorreto.

project 
|
-------docker-dir 

Construindo a partir do docker-dir, o seguinte foi bom

docker build -t br_base:0.1 . 

Construindo a partir do diretório-dock, o contexto de construção foi alterado. Portanto, eu precisava alterar o contexto no comando. O contexto é dado pelo '.' no comando acima.

O novo comando do diretório do projeto deve ser

docker build -t br_base:0.1 ./base

O contexto aqui é fornecido pela './base'


0

se você estiver criando imagem e recebendo o contexto de construção do envio de mensagens para o daemon do docker, o que está demorando para ser copiado,

adicione o arquivo .dockerignore . deve incluir os arquivos ou diretório que não precisam ser copiados.


0

Para NodeJS Application, adicione um .dockerignorearquivo ao diretório raiz do projeto e, dentro do .dockerignorearquivo, adicione o seguinte

node_modules
dist
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.