Docker como executar pip requirements.txt apenas se houver uma mudança?

98

Em um Dockerfile, tenho uma camada que instala requirements.txt:

FROM python:2.7
RUN pip install -r requirements.txt

Quando eu construo a imagem do docker, ela executa todo o processo, independentemente de quaisquer alterações feitas neste arquivo.

Como posso ter certeza de que o Docker só será executado pip install -r requirements.txtse houver uma alteração no arquivo?

Removing intermediate container f98c845d0f05
Step 3 : RUN pip install -r requirements.txt
 ---> Running in 8ceb63abaef6
Collecting https://github.com/tomchristie/django-rest-framework/archive/master.zip (from -r requirements.txt (line 30))
  Downloading https://github.com/tomchristie/django-rest-framework/archive/master.zip
Collecting Django==1.8.7 (from -r requirements.txt (line 1))
Prometeu
fonte
1
Por favor, poste a saída de docker build(e sua Dockerfile). Presumivelmente, é uma etapa anterior em seu processo de compilação que está invadindo o cache, fazendo com que esta etapa seja executada.
Thomas Orozco
atualize o OP com tudo o que tenho no momento
Prometheus
1
Apenas esta etapa não é útil. Por favor, poste a completa saída (ou pelo menos o Dockerfile).
Thomas Orozco

Respostas:

179

Estou supondo que, em algum ponto do processo de compilação, você está copiando todo o seu aplicativo para a imagem do Docker com COPYou ADD:

COPY . /opt/app
WORKDIR /opt/app
RUN pip install -r requirements.txt

O problema é que você está invalidando o cache de compilação do Docker sempre que copia o aplicativo inteiro na imagem. Isso também invalidará o cache para todas as etapas de construção subsequentes.

Para evitar isso, sugiro copiar apenas orequirements.txt arquivo em uma etapa de compilação separada antes de adicionar o aplicativo inteiro à imagem:

COPY requirements.txt /opt/app/requirements.txt
WORKDIR /opt/app
RUN pip install -r requirements.txt
COPY . /opt/app
# continue as before...

Como o arquivo de requisitos em si provavelmente muda apenas raramente, você poderá usar as camadas em cache até o ponto em que adicionar o código do aplicativo à imagem.

Helmbert
fonte
8
Como orientação geral, acredito que COPYseja preferível, a ADDmenos que você precise especificamente do comportamento de ADD.
Metrópolis
2
@ Metropolis, você está totalmente correto. Obrigado pela dica.
helmbert
5
Concordo com @Metropolis. ADDsó é necessário se a <src>pasta contiver algum arquivo que precise ser descompactado ou que precise suportar o tratamento remoto de URL. {código-fonte}
Mohsin
45

Isso é mencionado diretamente nas " Práticas recomendadas para escrever Dockerfiles " do próprio Docker :

Se você tiver várias etapas do Dockerfile que usam arquivos diferentes do seu contexto, COPIE-os individualmente, em vez de todos de uma vez. Isso garantirá que o cache de construção de cada etapa só seja invalidado (forçando a etapa a ser executada novamente) se os arquivos especificamente necessários forem alterados.

Por exemplo:

COPY requirements.txt /tmp/
RUN pip install --requirement /tmp/requirements.txt
COPY . /tmp/

Resulta em menos invalidações de cache para a etapa RUN do que se você colocasse COPY. / tmp / antes disso.

jrc
fonte
0

Alternativamente, como um meio mais rápido de executar o arquivo requirements.txt sem digitar "sim" para confirmar a instalação das bibliotecas, você pode reescrever como:

COPY requirements.txt ./
RUN pip install -y -r requirements.txt
COPY ./"dir"/* .
Asante Michael
fonte