Meu Dockerfile é algo como
FROM my/base
ADD . /srv
RUN pip install -r requirements.txt
RUN python setup.py install
ENTRYPOINT ["run_server"]
Cada vez que construo uma nova imagem, as dependências precisam ser reinstaladas, o que pode ser muito lento na minha região.
Uma maneira que penso em cache
pacotes que foram instalados é substituir a my/base
imagem por imagens mais recentes como esta:
docker build -t new_image_1 .
docker tag new_image_1 my/base
Então, da próxima vez que eu construir com este Dockerfile, meu / base já tem alguns pacotes instalados.
Mas esta solução tem dois problemas:
- Nem sempre é possível substituir uma imagem de base
- A imagem de base fica cada vez maior conforme novas imagens são colocadas em camadas
Então, que solução melhor eu poderia usar para resolver esse problema?
EDITAR##:
Algumas informações sobre o docker em minha máquina:
☁ test docker version
Client version: 1.1.2
Client API version: 1.13
Go version (client): go1.2.1
Git commit (client): d84a070
Server version: 1.1.2
Server API version: 1.13
Go version (server): go1.2.1
Git commit (server): d84a070
☁ test docker info
Containers: 0
Images: 56
Storage Driver: aufs
Root Dir: /var/lib/docker/aufs
Dirs: 56
Execution Driver: native-0.2
Kernel Version: 3.13.0-29-generic
WARNING: No swap limit support
my/base
Respostas:
Tente construir um Dockerfile que se pareça com isto:
O Docker usará o cache durante a instalação do pip, desde que você não faça alterações no
requirements.txt
, independentemente do fato de outros arquivos de código em.
terem sido alterados ou não. Aqui está um exemplo.Aqui está um
Hello, World!
programa simples :A saída do docker build:
Vamos modificar
run.py
:Tente construir novamente, abaixo está o resultado:
Como você pode ver acima, desta vez, o docker usa o cache durante a construção. Agora, vamos atualizar
requirements.txt
:Abaixo está a saída do docker build:
Observe como o docker não usou o cache durante a instalação do pip. Se não funcionar, verifique a versão do docker.
fonte
ADD
instrução, o cache é invalidado.ADD ./requirements.txt /srv/requirements.txt
), então o docker deve usar o cache. Consulte adicionar seção no documento Dockerfile.ADD requirements.txt /srv
antes de executar pip (RUN pip install -r requirements.txt
) e adicionar todos os outros arquivos após executar pip. Portanto, eles devem estar na seguinte ordem: (1)ADD requirements.txt /srv
; (2)RUN pip install -r requirements.txt
; ( 3)ADD . /srv
Para minimizar a atividade da rede, você pode apontar
pip
para um diretório de cache em sua máquina host.Execute seu contêiner do docker com o vínculo do diretório de cache do seu host montado no diretório de cache do seu contêiner.
docker run
comando deve ser semelhante a este:Em seguida, em seu Dockerfile, instale seus requisitos como parte da
ENTRYPOINT
instrução (ouCMD
instrução) em vez de como umRUN
comando. Isso é importante porque (conforme apontado nos comentários) a montagem não está disponível durante a construção da imagem (quando asRUN
instruções são executadas). O arquivo Docker deve ser semelhante a este:fonte
Eu entendo que esta pergunta já tem algumas respostas populares. Mas existe uma maneira mais recente de armazenar arquivos em cache para gerenciadores de pacotes. Acho que pode ser uma boa resposta no futuro, quando o BuildKit se tornar mais padrão.
A partir do Docker 18.09, há suporte experimental para BuildKit . BuildKit adiciona suporte para alguns novos recursos no Dockerfile, incluindo suporte experimental para montar volumes externos em
RUN
etapas. Isso nos permite criar caches para coisas como$HOME/.cache/pip/
.Usaremos o seguinte
requirements.txt
arquivo como exemplo:Um exemplo típico de Python
Dockerfile
pode ser semelhante a:Com BuildKit ativado usando a
DOCKER_BUILDKIT
variável de ambiente, podemos construir apip
etapa sem cache em cerca de 65 segundos:Agora, vamos adicionar o cabeçalho experimental e modificar a
RUN
etapa para armazenar em cache os pacotes Python:Vá em frente e faça outra construção agora. Deve demorar o mesmo tempo. Mas desta vez ele está armazenando em cache os pacotes Python em nossa nova montagem de cache:
Cerca de 60 segundos. Semelhante à nossa primeira construção.
Faça uma pequena alteração no
requirements.txt
(como adicionar uma nova linha entre dois pacotes) para forçar uma invalidação do cache e execute novamente:Apenas cerca de 16 segundos!
Estamos obtendo essa velocidade porque não estamos mais baixando todos os pacotes Python. Eles foram armazenados em cache pelo gerenciador de pacotes (
pip
neste caso) e armazenados em uma montagem de volume de cache. A montagem do volume é fornecida para a etapa de execução para quepip
possa reutilizar nossos pacotes já baixados. Isso acontece fora de qualquer cache de camada do Docker .Os ganhos devem ser muito melhores em maiores
requirements.txt
.Notas:
As coisas do BuildKit não funcionam no Docker Compose ou em outras ferramentas que usam diretamente a API Docker no momento.Agora há suporte para isso no Docker Compose a partir de 1.25.0. Veja como você habilita BuildKit com docker-compose?docker system prune -a
.Esperançosamente, esses recursos chegarão ao Docker para construção e o BuildKit se tornará o padrão. Se / quando isso acontecer, tentarei atualizar esta resposta.
fonte
Dockerfile
ou a versão do Docker é muito antiga. Gostaria de criar uma nova pergunta com todas as suas informações de depuração.Descobri que a melhor maneira é simplesmente adicionar o diretório Python site-packages como um volume.
Desta forma, posso instalar novas bibliotecas sem ter que fazer uma reconstrução completa.
EDIT : Desconsidere esta resposta, a resposta de jkukul acima funcionou para mim. Minha intenção era armazenar em cache a pasta de pacotes do site . Isso seria mais parecido com:
Armazenar a pasta de download em cache é muito mais limpo. Isso também armazena em cache as rodas, de modo que realiza a tarefa corretamente.
fonte