web-dev-qa-db-fra.com

Comment empêcher une instruction Dockerfile d'être mise en cache?

Dans ma Dockerfile j'utilise curl ou ADD pour télécharger la dernière version d'une archive telle que:

FROM debian:jessie
...
RUN apt-get install -y curl
...
RUN curl -sL http://example.com/latest/archive.tar.gz --output archive.tar.gz
...
ADD http://example.com/latest/archive2.tar.gz
...

L'instruction RUN qui utilise curl ou ADD crée son propre calque d'image. Cela servira de cache pour les futures exécutions de docker build.

Question: Comment puis-je désactiver la mise en cache pour ces instructions?

Il serait bon d’obtenir quelque chose comme invalidation du cache dans cet emplacement. Par exemple. en utilisant HTTP ETags ou en interrogeant le champ d'en-tête dernière modification}. Cela donnerait la possibilité d'effectuer une vérification rapide basée sur les en-têtes HTTP pour décider si une couche en cache peut être utilisée ou non.

Je sais que certaines astuces peuvent vous aider, par exemple. l'exécution d'un script Shell de téléchargement dans l'instruction RUN à la place. Son nom de fichier sera modifié avant que le docker build soit déclenché par notre système de construction. Et je pourrais faire les vérifications HTTP à l'intérieur de ce script. Mais ensuite, j'ai besoin de stocker le dernier ETag utilisé ou le dernière modification utilisée dans un fichier quelque part. Je me demande s’il existe une fonctionnalité plus propre et native Docker que je pourrais utiliser ici.

22
h3nrik

Un argument de construction peut être spécifié pour forcer le cache à partir de cette étape. Par exemple, dans votre Dockerfile, mettez

ARG CACHE_DATE=not_a_date

et donnez ensuite à cet argument une nouvelle valeur à chaque nouvelle construction. Le meilleur, bien sûr, est l'horodatage. 

docker build --build-arg CACHE_DATE=$(date +%Y-%m-%d:%H:%M:%S) ...

Assurez-vous que la valeur est une chaîne sans espaces, sinon le client Docker le prendra faussement comme plusieurs arguments. 

Voir une discussion détaillée sur numéro 22832

21
Ruifeng Ma

docker build --no-cache invaliderait le cache pour tout les commandes.

Commande ADD de Dockerfile utilisé pour faire invalider le cache. Bien que il ait été amélioré dans la version récente de docker:

Docker est censé contrôler tous les fichiers ajoutés via ADD, puis décider s’il doit utiliser le cache ou non.

Ainsi, si le fichier ajouté a changé, le cache doit être invalidé pour la commande ADD.


Numéro 1326 mentionne d'autres conseils:

Cela a fonctionné.

RUN yum -y install firefox #redo

Il semble donc que Docker relance l’étape (et toutes les étapes suivantes) si la chaîne que je passe à la commande RUN change de toute façon - même si ce n’est qu’un commentaire.

Le cache de docker est utilisé uniquement et uniquement si aucun de ses ancêtres n'a changé (ce comportement est logique, car la commande suivante ajoutera des modifications au calque précédent).

Le cache est utilisé s'il n'y a pas de caractère qui a changé (même un espace suffit pour invalider un cache).

26
VonC

Passer l'argument du fichier de construction ne fonctionnait pas avec moi pour une raison quelconque. J'ai résolu le mien en ajoutant la commande que je ne veux pas mettre en cache à la dernière instruction CMD.

Par exemple:

CMD ["/bin/bash", "-c" , "python3 /foo.py && bash /bar.sh"]

Maintenant, je lance foo.py et je ne veux pas être mis en cache, alors bar.sh. Pas propre, mais ça marche.

0
Ahmed