Eu fiz uma imagem simples através do Dockerfile do Fedora (inicialmente 320 MB).
Adicionado o Nano (este pequeno editor de 1 MB), e o tamanho da imagem aumentou para 530 MB. Adicionei Git em cima disso (30 MB) e, em seguida, meu tamanho de imagem dispara para 830 MB.
Isso não é loucura?
Tentei exportar e importar contêiner para remover imagens históricas / intermediárias. Esse esforço economizou até 25 MB, agora o tamanho da minha imagem é 804 MB. Eu também tentei executar muitos comandos em um RUN
, mas ainda estou recebendo os mesmos 830 MB iniciais.
Estou com minhas dúvidas se vale a pena usar o Docker. Quero dizer, eu mal instalei nada e estou atingindo 1 GB. Se eu tiver que adicionar coisas sérias, como um banco de dados e assim por diante, posso ficar sem espaço em disco.
Alguém sofre de tamanho ridículo de imagens? Como você lida com isso?
A menos que meu Dockerfile esteja terrivelmente incorreto?
FROM fedora:latest
MAINTAINER Me NotYou <[email protected]>
RUN yum -y install nano
RUN yum -y install git
mas é difícil imaginar o que poderia dar errado aqui.
yum clean all
algum efeito no tamanho?docker images
qual, na última coluna, afirma um pesado 830MB. Talvez eu não saiba de fato qual é o tamanho real da minha imagem, já que o comando docker images indica que esse 830MB é de tamanho virtual. Mas, novamente, qual é o tamanho real da imagem?Respostas:
Como o @rexposadas disse, as imagens incluem todas as camadas e cada camada inclui todas as dependências para o que você instalou. Também é importante observar que as imagens de base (como
fedora:latest
tendem a ser muito simples. Você pode se surpreender com o número de dependências que o software instalado possui.Consegui diminuir significativamente sua instalação adicionando
yum -y clean all
a cada linha:É importante fazer isso para cada RUN, antes que a camada seja confirmada ou as exclusões não removem os dados. Ou seja, em um sistema de arquivos de união / cópia na gravação, a limpeza no final não reduz realmente o uso do sistema de arquivos porque os dados reais já estão comprometidos com as camadas inferiores. Para contornar isso, você deve limpar em cada camada.
fonte
docker images
). É possível remover / excluir / destruir essas camadas antigas? Para ser mais específico: eu gostaria de remover completamente (com base no seu exemplo) imagens: 172743bd5d60, 3f2fed40e4b0, fd241224e9cf, 511136ea3c5a da história, para que o tamanho da minha imagem virtual seja mais ou menos o tamanho da imagem final, aqui ~ 260MB .docker export
e depoisdocker import
novamente. Isso achataria as camadas. Eu não acho que isso reduziria o tamanho, mas eu poderia estar errado.docker ps -s
mostra o tamanho real do disco rígido, que no meu caso era-1B
. Isso parece razoável, menos 1 byte . Eu ganhei algum espaço no HDD ... parece legítimo.As imagens do Docker não são grandes, você está apenas criando imagens grandes.
A
scratch
imagem é 0B e você pode usá-lo para empacotar seu código, se for possível compilar seu código em um binário estático. Por exemplo, você pode compilar seu programa Go e empacotá-lo em cimascratch
para criar uma imagem totalmente utilizável com menos de 5 MB.A chave é não usar as imagens oficiais do Docker, pois elas são muito grandes. O zero não é tão prático assim, então eu recomendo usar o Alpine Linux como sua imagem base. Tem ~ 5 MB e adicione apenas o necessário para o seu aplicativo. Este post sobre microcontainers mostra como criar imagens muito pequenas baseadas no Alpine.
ATUALIZAÇÃO: as imagens oficiais do Docker agora são baseadas em alpinos, portanto, é bom usá-las agora.
fonte
Aqui estão mais algumas coisas que você pode fazer :
RUN
comandos onde puder. Coloque o máximo possível em umRUN
comando (usando&&
)Com esses dois AND as recomendações de @Andy e @michau, eu fui capaz de redimensionar minha imagem nodejs de 1.062 GB para 542 MB.
Edit: Mais uma coisa importante: "Demorei um pouco para entender realmente que cada comando do Dockerfile cria um novo contêiner com os deltas. [...] Não importa se você rm -rf os arquivos em um comando posterior; eles continuam a existir em algum contêiner de camada intermediária ". Então agora eu consegui colocar
apt-get install
,wget
,npm install
(com dependências git) eapt-get remove
em um únicoRUN
comando, então agora a minha imagem tem apenas 438 MB.Editar 29/06/17
Com o Docker v17.06, surgem novos recursos para os Dockerfiles: você pode ter várias
FROM
instruções em um Dockerfile e apenas as últimas coisasFROM
estarão na sua imagem final do Docker. Isso é útil para reduzir o tamanho da imagem, por exemplo:Irá resultar em uma imagem com apenas a imagem base nodejs mais o conteúdo de / var / my-project desde os primeiros passos - mas sem o ruby, python, git, openssh e gcc!
fonte
Sim, esses tamanhos são ridículos, e eu realmente não tenho idéia do por que tão poucas pessoas percebem isso.
Eu criei uma imagem do Ubuntu que é realmente mínima (ao contrário de outras chamadas imagens "mínimas"). É chamado
textlab/ubuntu-essential
e tem 60 MB.A imagem acima tem 82 MB após a instalação do nano.
O Git tem muitos outros pré-requisitos, portanto a imagem fica maior, cerca de 192 MB. Ainda é menor que o tamanho inicial da maioria das imagens.
Você também pode dar uma olhada no script que escrevi para criar a imagem mínima do Ubuntu para o Docker . Talvez você possa adaptá-lo ao Fedora, mas não sei quanto você poderá desinstalar.
fonte
O seguinte me ajudou muito:
Após remover os pacotes não utilizados (por exemplo, redis 1200 mb liberados) dentro do meu contêiner, fiz o seguinte:
As camadas ficam achatadas. O tamanho da nova imagem será menor porque removi os pacotes do contêiner, conforme indicado acima.
Demorou muito tempo para entender isso e é por isso que adicionei meu comentário.
fonte
docker export <CONTAINER ID> | docker import - some-image-name:latest
Para práticas recomendadas, você deve executar um único comando RUN, porque cada instrução RUN no Dockerfile grava uma nova camada na imagem e cada camada requer espaço extra no disco. Para manter o número mínimo de camadas, qualquer manipulação de arquivo, como instalar, mover, extrair, remover, etc, deve ser idealmente feita sob uma única instrução RUN
fonte
O Docker Squash é uma solução muito boa para isso. você pode,
$packagemanager clean
na última etapa, em vez de em todas as linhas e, em seguida, basta executar uma aba Docker para se livrar de todas as camadas.https://github.com/jwilder/docker-squash
fonte
Sim, o sistema de camadas é bastante surpreendente. Se você possui uma imagem base e a incrementa, faça o seguinte:
A imagem tem exatamente o mesmo tamanho. Essencialmente, isso significa que você precisa colocar em suas etapas RUN muitas técnicas de extração, instalação e limpeza para tornar as imagens tão pequenas quanto o software instalado.
Isso torna a vida muito mais difícil ...
O dockerBuild está ausente nas etapas RUN sem confirmação.
fonte