Docker comment exécuter pip requirements.txt uniquement s'il y a eu un changement?

91

Dans un Dockerfile, j'ai une couche qui installe requirements.txt:

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

Lorsque je crée l'image docker, il exécute tout le processus, quelles que soient les modifications apportées à ce fichier.

Comment puis-je m'assurer que Docker ne s'exécute qu'en pip install -r requirements.txtcas de modification du fichier?

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))
Prométhée
la source
1
Veuillez publier la sortie de docker build(et votre Dockerfile). Vraisemblablement, c'est une étape antérieure de votre processus de construction qui détruit le cache, provoquant l'exécution de cette étape.
Thomas Orozco
mettre à jour OP avec tout ce que j'ai pour le moment
Prometheus
1
Cette étape n'est pas utile. Veuillez publier la sortie complète (ou au moins le Dockerfile).
Thomas Orozco

Réponses:

171

Je suppose qu'à un moment donné de votre processus de construction, vous copiez l'intégralité de votre application dans l'image Docker avec COPYou ADD:

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

Le problème est que vous invalidez le cache de build Docker chaque fois que vous copiez l'application entière dans l'image. Cela invalidera également le cache pour toutes les étapes de construction suivantes.

Pour éviter cela, je suggérerais de nerequirements.txt copier que le fichier dans une étape de construction distincte avant d'ajouter l'application entière à l'image:

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

Comme le fichier d'exigences lui-même ne change probablement que rarement, vous pourrez utiliser les couches mises en cache jusqu'au moment où vous ajoutez votre code d'application dans l'image.

Helmbert
la source
8
En règle générale, je pense que COPYc'est préférable à ADDmoins que vous n'ayez spécifiquement besoin du comportement de ADD.
Metropolis
2
@Metropolis, vous avez tout à fait raison. Merci pour l'indice.
helmbert
5
D'accord avec @Metropolis. ADDn'est nécessaire que si le <src>dossier contient une archive qui doit être décompressée ou qui doit prendre en charge la gestion d'URL à distance. {code source}
Mohsin
44

Ceci est directement mentionné dans les " Meilleures pratiques pour l'écriture de fichiers Docker " de Docker :

Si vous avez plusieurs étapes Dockerfile qui utilisent des fichiers différents de votre contexte, COPIEZ-les individuellement, plutôt que tous à la fois. Cela garantira que le cache de construction de chaque étape n'est invalidé (obligeant l'étape à être réexécutée) que si les fichiers spécifiquement requis changent.

Par exemple:

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

Il en résulte moins d'invalidations de cache pour l'étape RUN que si vous placez COPY. / tmp / avant.

jrc
la source
0

Alternativement, comme moyen plus rapide d'exécuter le fichier requirements.txt sans taper «oui» pour confirmer l'installation des bibliothèques, vous pouvez réécrire comme:

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