web-dev-qa-db-fra.com

Comment Docker sait-il quand utiliser le cache pendant une build et quand non?

Je suis étonné de voir à quel point la mise en cache des couches de Docker fonctionne, mais je me demande également comment il détermine s'il peut utiliser une couche en cache ou non.

Prenons ces étapes de construction par exemple:

Step 4 : RUN npm install -g   node-gyp
 ---> Using cache
 ---> 3fc59f47f6aa
Step 5 : WORKDIR /src
 ---> Using cache
 ---> 5c6956ba5856
Step 6 : COPY package.json .
 ---> d82099966d6a
Removing intermediate container eb7ecb8d3ec7
Step 7 : RUN npm install
 ---> Running in b960cf0fdd0a

Par exemple, comment sait-il qu'il peut utiliser la couche mise en cache pour npm install -g node-gyp mais crée un nouveau calque pour npm install?

33
Hedge

Le processus de création du cache est expliqué de manière assez détaillée dans la section Dockerfile best practices build cache .

  • En commençant par une image de base qui est déjà dans le cache, l'instruction suivante est comparée à toutes les images enfants dérivées de cette image de base pour voir si l'une d'entre elles a été créée en utilisant exactement la même instruction. Sinon, le cache est invalidé.

  • Dans la plupart des cas, il suffit de comparer l'instruction dans le Dockerfile avec l'une des images enfants. Cependant, certaines instructions nécessitent un peu plus d'examen et d'explication.

  • Pour les instructions ADD et COPY, le contenu du ou des fichiers dans l'image est examiné et une somme de contrôle est calculée pour chaque fichier. Les heures de dernière modification et de dernier accès du ou des fichiers ne sont pas prises en compte dans ces sommes de contrôle. Pendant la recherche de cache, la somme de contrôle est comparée à la somme de contrôle dans les images existantes. Si quelque chose a changé dans le ou les fichiers, comme le contenu et les métadonnées, le cache est invalidé.

  • Mis à part les commandes ADD et COPY, la vérification du cache ne cherchera pas les fichiers dans le conteneur pour déterminer une correspondance de cache. Par exemple, lors du traitement d'un RUN apt-get -y update commande les fichiers mis à jour dans le conteneur ne seront pas examinés pour déterminer s'il existe un hit de cache. Dans ce cas, seule la chaîne de commande elle-même sera utilisée pour trouver une correspondance.

Une fois le cache invalidé, toutes les commandes Dockerfile suivantes généreront de nouvelles images et le cache ne sera pas utilisé.

Vous rencontrerez des situations dans lesquelles des packages de système d'exploitation, des packages NPM ou un dépôt Git sont mis à jour vers des versions plus récentes (disons un ~2.3 semver dans package.json) mais comme votre Dockerfile ou package.json n'a pas été mis à jour, docker continuera d'utiliser le cache.

Il est possible de générer par programmation un Dockerfile qui perturbe le cache en modifiant les lignes sur certains contrôles plus intelligents (par exemple, récupérer le dernier shasum de branche git à partir d'un référentiel pour l'utiliser dans l'instruction clone). Vous pouvez également exécuter périodiquement la génération avec --no-cache=true pour appliquer les mises à jour.

33
Matt

C'est parce que votre package.json le fichier a été modifié, voir Removing intermediate container.

C'est aussi généralement la raison pour laquelle les fichiers d'informations du gestionnaire de packages (fournisseur/tiers) sont COPY 'édités en premier pendant docker build. Après cela, vous exécutez l'installation du gestionnaire de packages, puis vous ajoutez le reste de votre application, c'est-à-dire src.

Si vous n'avez apporté aucune modification à vos bibliothèques, ces étapes sont exécutées à partir du cache de génération.

6
schmunk