Docker ¿cómo ejecutar pip requirements.txt solo si hubo un cambio?

91

En un Dockerfile tengo una capa que instala requirements.txt:

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

Cuando construyo la imagen de la ventana acoplable, se ejecuta todo el proceso independientemente de los cambios realizados en este archivo.

¿Cómo me aseguro de que Docker solo se ejecute pip install -r requirements.txtsi ha habido un cambio en el archivo?

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))
Prometeo
fuente
1
Publique la salida de docker build(y su Dockerfile). Presumiblemente, es un paso anterior en su proceso de compilación el que está destruyendo el caché, lo que hace que se ejecute este paso.
Thomas Orozco
actualizar OP con todo lo que tengo en este momento
Prometheus
1
Solo este paso no es útil. Por favor, después de la completa salida (o al menos la Dockerfile).
Thomas Orozco

Respuestas:

171

Supongo que en algún momento de su proceso de compilación, está copiando toda su aplicación en la imagen de Docker con COPYo ADD:

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

El problema es que invalida la caché de compilación de Docker cada vez que copia la aplicación completa en la imagen. Esto también invalidará la caché para todos los pasos de compilación posteriores.

Para evitar esto, sugiero copiar solo elrequirements.txt archivo en un paso de compilación separado antes de agregar la aplicación completa a la imagen:

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

Como el archivo de requisitos en sí mismo probablemente cambia solo en raras ocasiones, podrá usar las capas almacenadas en caché hasta el momento en que agregue el código de su aplicación a la imagen.

Helmbert
fuente
8
Como pauta general, creo que COPYse prefiere a ADDmenos que necesite específicamente el comportamiento de ADD.
Metropolis
2
@Metropolis, tienes toda la razón. Gracias por la pista.
helmbert
5
De acuerdo con @Metropolis. ADDsolo es necesario si la <src>carpeta contiene algún archivo que deba descomprimirse o sea compatible con el manejo remoto de URL. {código fuente}
Mohsin
44

Esto se menciona directamente en las " Mejores prácticas para escribir Dockerfiles " de Docker :

Si tiene varios pasos de Dockerfile que usan diferentes archivos de su contexto, COPÍPELOS individualmente, en lugar de todos a la vez. Esto asegurará que la caché de compilación de cada paso solo se invalide (obligando a que el paso se vuelva a ejecutar) si cambian los archivos específicamente requeridos.

Por ejemplo:

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

Da como resultado menos invalidaciones de caché para el paso RUN que si pones COPY. / tmp / antes.

jrc
fuente
0

Alternativamente, como un medio más rápido para ejecutar el archivo requirements.txt sin escribir "sí" para confirmar la instalación de las bibliotecas, puede volver a escribir como:

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