E-NO
DevOps 10 min de lecture

Mise en cache des couches Docker : concepts avancés et exemples pratiques

calendar_today Publié : 2026-09-04
update Dernière mise à jour : 2026-09-04
analytics Efficacité SEO : 100%
Illustration du guide technique pour « Mise en cache des couches Docker : concepts avancés et exemples pratiques ».

Introduction

La mise en cache des couches Docker peut accélérer considérablement les builds d'images et réduire les coûts de CI, mais beaucoup d'équipes ne comprennent que les bases : « si la ligne du Dockerfile ne change pas, le cache est réutilisé ». La réalité est plus complexe. BuildKit, les builds multi-étapes, les montages de cache et même l'ordre des instructions COPY peuvent invalider silencieusement votre cache ou vous faire manquer des optimisations importantes.

Cet article va au-delà des bases pour expliquer les concepts avancés de mise en cache des couches avec des exemples pratiques. Vous apprendrez comment le cache de Docker fonctionne sous le capot, comment l'inspecter, comment concevoir des Dockerfiles pour une réutilisation maximale du cache et comment récupérer lorsque le cache vous fait défaut. Chaque concept est associé à une commande concrète, une sortie attendue et des conseils de dépannage pour que vous puissiez appliquer ces techniques immédiatement.

L'objectif est la sécurité opérationnelle : observer avant de modifier, limiter le rayon d'impact, utiliser des espaces réservés au lieu de secrets, vérifier le résultat et documenter comment récupérer si l'état attendu n'est pas atteint.

Inventaire de l'environnement et de la version

Avant de déboguer le comportement du cache, établissez une image claire de votre environnement Docker. L'implémentation du cache diffère entre le builder hérité et BuildKit, et le comportement varie selon les versions de Docker.

Vérifier la version de Docker et le builder

Exécutez les commandes suivantes pour identifier votre version de Docker et le builder actif :

docker version --format '{{.Server.Version}}'
docker buildx version
docker system info --format '{{.Driver}}'

Exemple de sortie attendue :

24.0.7
v0.12.1
overlay2

Si BuildKit est activé (par défaut dans Docker 23+), vous verrez buildkit comme pilote du builder. Pour vérifier directement :

docker buildx ls

Cherchez un builder avec * indiquant qu'il est courant. Si vous ne voyez que le builder par défaut avec DOCKER_BUILDKIT=0 dans sa configuration, vous utilisez le builder hérité et devriez envisager d'activer BuildKit pour un meilleur contrôle du cache.

Prérequis

  • Docker Engine 20.10 ou ultérieur (BuildKit activé par défaut)
  • Familiarité de base avec les Dockerfiles et docker build
  • Un projet de test avec un Dockerfile pour l'expérimentation

Observer l'état actuel du cache

Pour voir combien d'espace disque le cache de build utilise :

docker system df

Exemple de sortie (tronquée) :

TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          12        3         2.45GB    1.2GB (49%)
Containers      5         2         150MB     100MB (66%)
Local Volumes   8         4         1.1GB     500MB (45%)
Build Cache     42        18        3.8GB     2.9GB (76%)

Cela montre l'utilisation du cache de build et combien pourrait être récupéré avec docker builder prune.

Emplacement des données et test de redémarrage

Lorsque le cache est stocké dans un volume, confirmez où les fichiers persistent. Pour un volume nommé :

docker volume inspect app_data

La sortie inclut le point de montage sur l'hôte. Si vous utilisez un montage bind (par exemple, ./data:/var/lib/app), assurez-vous que le chemin hôte existe et est accessible en écriture. Un test de redémarrage vérifie la persistance :

docker run -d --name test-app -v app_data:/var/lib/app myimage
# écrire des données dans le conteneur
docker exec test-app sh -c "echo hello > /var/lib/app/test.txt"
docker stop test-app
docker rm test-app
docker run -d --name test-app -v app_data:/var/lib/app myimage
docker exec test-app cat /var/lib/app/test.txt

Si le fichier n'apparaît pas, le volume n'a pas été monté correctement ou l'application a écrit dans un chemin différent.

Chemin de configuration sûr

Configurer le comportement du cache doit être délibéré et réversible. Les étapes suivantes vous guident pour activer BuildKit, utiliser les montages de cache et configurer le stockage de cache externe.

Activer BuildKit

Pour Docker 23+, BuildKit est activé par défaut. Pour les versions plus anciennes, définissez la variable d'environnement :

export DOCKER_BUILDKIT=1
docker build -t myapp:latest .

Vérifiez que BuildKit est actif en vérifiant le support des montages de cache :

docker build --progress=plain --no-cache -t test . 2>&1 | grep -i buildkit

Si vous ne voyez pas d'erreurs, BuildKit est probablement actif. Vous pouvez également vérifier :

docker buildx debug build --invoke /bin/true .

Utiliser les montages de cache pour les dépendances

L'une des techniques avancées les plus impactantes est l'utilisation de montages de cache dans les instructions RUN pour conserver les caches des gestionnaires de paquets entre les builds. Exemple pour un projet Node.js :

# syntax=docker/dockerfile:1
FROM node:20-alpine
WORKDIR /app
COPY package.json yarn.lock ./
RUN --mount=type=cache,target=/root/.yarn \
    yarn install --frozen-lockfile
COPY . .
RUN yarn build

Ici, le répertoire de cache Yarn /root/.yarn est stocké dans un montage de cache qui persiste entre les builds même si la couche RUN est invalidée. La ligne COPY package.json yarn.lock garantit que l'installation des dépendances ne s'exécute à nouveau que lorsque ces fichiers changent.

Pour vérifier que le montage de cache fonctionne, construisez deux fois avec un changement uniquement dans le code source (pas les fichiers de paquets). Le deuxième build devrait ignorer l'étape yarn install et afficher CACHED pour cette couche :

#7 [3/5] COPY package.json yarn.lock ./
#7 CACHED
#8 [4/5] RUN --mount=type=cache,target=/root/.yarn yarn install --frozen-lockfile
#8 CACHED

Pour Python avec pip :

RUN --mount=type=cache,target=/root/.cache/pip pip install -r requirements.txt

Pour les modules Go :

RUN --mount=type=cache,target=/go/pkg/mod go mod download

Configurer le cache externe (registre ou local)

BuildKit prend en charge l'exportation du cache vers un registre ou un répertoire local pour le partager entre les exécutions CI. Pour un cache de registre :

docker buildx build --cache-to=type=registry,ref=myregistry/cache:myapp --cache-from=type=registry,ref=myregistry/cache:myapp -t myapp:latest .

Pour un répertoire de cache local :

docker buildx build --cache-to=type=local,dest=./build-cache --cache-from=type=local,src=./build-cache -t myapp:latest .

Ceci est particulièrement utile en CI où vous ne pouvez pas compter sur la persistance du cache Docker local entre les tâches.

Sécurité : utilisez des espaces réservés, pas des secrets

Dans les arguments de build ou les variables d'environnement, ne passez jamais de vrais secrets directement. Utilisez les secrets BuildKit :

# syntax=docker/dockerfile:1
FROM alpine
RUN --mount=type=secret,id=mysecret cat /run/secrets/mysecret

Passez le secret au moment du build :

docker build --secret id=mysecret,src=./secret.txt -t myapp .

Cela garantit que le secret n'est pas intégré dans la couche d'image ou le cache.

Vérification et diagnostic

Après avoir configuré la mise en cache, vous devez vérifier qu'elle fonctionne et diagnostiquer quand ce n'est pas le cas. Cette section fournit des commandes concrètes pour inspecter l'utilisation du cache, analyser les reconstructions de couches et résoudre les problèmes courants.

Inspecter la sortie du build pour les hits de cache

Construisez toujours avec --progress=plain pour voir un journal clair couche par couche :

docker build --progress=plain -t myapp:latest .

Exemple de sortie :

#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile: 150B done
#1 DONE 0.0s
#2 [internal] load .dockerignore
#2 transferring context: 2B done
#2 DONE 0.0s
#3 [internal] load metadata for docker.io/library/node:20-alpine
#3 DONE 1.2s
#4 [1/5] FROM docker.io/library/node:20-alpine
#4 CACHED
#5 [2/5] WORKDIR /app
#5 CACHED
#6 [3/5] COPY package.json yarn.lock ./
#6 CACHED
#7 [4/5] RUN --mount=type=cache,target=/root/.yarn yarn install --frozen-lockfile
#7 CACHED
#8 [5/5] COPY . .
#8 CACHED
#9 exporting to image
#9 exporting layers 0.2s done
#9 writing image sha256:... done

Chaque ligne avec CACHED signifie que la couche a été réutilisée. Si vous voyez DONE avec un horodatage, cette couche a été reconstruite.

Analyser le cache avec BuildKit Debug

Pour une analyse plus approfondie, utilisez buildx debug pour inspecter le graphe de build et les entrées de cache :

docker buildx debug build --invoke /bin/true .

Cela imprime le plan de build complet, y compris les étapes et leurs clés de cache. Vous pouvez également utiliser --print=outline :

docker buildx build --print=outline -t myapp:latest .

La sortie attendue montre les étapes du Dockerfile avec leurs étapes correspondantes et leurs dépendances.

Vérifier la taille du cache et le nettoyer

Pour voir l'utilisation actuelle du cache :

docker builder du

Exemple de sortie :

ID                                              RECLAIMABLE    SIZE       LAST ACCESSED
m3p5n7v9w2x1y4z6a8b0c                          true           1.5GB      2 hours ago
...
Total:                                          3.8GB

Pour nettoyer uniquement le cache inutilisé :

docker builder prune

Pour tout nettoyer y compris le cache actif (à utiliser avec prudence) :

docker builder prune -a

Dépannage des échecs de cache courants

Symptôme : Une couche est reconstruite même si son instruction n'a pas changé.

  • Cause : Une couche précédente a changé, modifiant le contexte de cette couche. Dans Docker, la clé de cache de chaque couche inclut le contenu de toutes les couches précédentes.
  • Correctif : Réorganisez les instructions pour placer les instructions fréquemment modifiées plus tard. Par exemple, déplacez COPY . . après l'installation des dépendances.

Symptôme : Le cache n'est pas utilisé du tout.

  • Vérifiez si BuildKit est activé : docker buildx ls
  • Vérifiez si --no-cache a été passé par inadvertance.
  • Vérifiez si le Dockerfile a une directive # syntax incompatible avec votre version de BuildKit.

Symptôme : Les montages de cache ne semblent pas persister entre les builds.

  • Assurez-vous d'utiliser BuildKit. Le builder hérité ignore les drapeaux --mount.
  • Assurez-vous que l'instruction RUN avec --mount n'est pas invalidée par des changements de couches antérieures. Le montage de cache persiste indépendamment, mais le RUN sera réexécuté et le montage ne sera réutilisé que si le cache de la couche précédente est valide.
  • Vérifiez que le chemin cible correspond au répertoire de cache de l'outil. Par exemple, le cache Yarn peut être à /usr/local/share/.cache/yarn selon l'image de base.

Modes de défaillance et récupération

Même avec une conception soignée, des échecs de cache surviennent. Cette section couvre les modes de défaillance courants, comment les détecter et comment récupérer sans casser votre build.

Défaillance : empoisonnement du cache avec des dépendances obsolètes

Si vous utilisez une balise flottante comme node:20 ou que vous comptez sur un gestionnaire de paquets qui résout les versions de manière lâche, vous pouvez obtenir une couche en cache avec des dépendances obsolètes. Même si le Dockerfile n'a pas changé, les versions des paquets sous-jacents peuvent avoir changé en amont, mais le cache ne le saura pas.

Détection :

  • Examinez le journal de build pour l'horodatage de la couche RUN. S'il est plus ancien que prévu, vous utilisez peut-être un ancien cache.
  • En CI, surveillez les avis de sécurité dans les dépendances et forcez périodiquement une invalidation du cache.

Récupération :

  • Épinglez les images de base par empreinte : FROM node:20-alpine@sha256:...
  • Utilisez des fichiers de verrouillage des dépendances et assurez-vous qu'ils sont copiés avant les commandes d'installation RUN.
  • Utilisez périodiquement --no-cache ou docker builder prune -af pour forcer une reconstruction complète, mais uniquement de manière contrôlée.

Défaillance : gonflement du cache et pression sur le disque

Au fil du temps, le cache de build peut consommer de grandes quantités d'espace disque, provoquant des échecs de build par manque d'espace sur le périphérique.

Détection :

  • Exécutez docker system df et vérifiez la ligne Build Cache.
  • Surveillez l'utilisation du disque sur la racine de données Docker (/var/lib/docker).

Récupération :

  • Utilisez docker builder prune avec des filtres pour supprimer l'ancien cache :
  docker builder prune --filter "until=24h"
  • Définissez une politique de rétention dans la configuration du démon Docker :
  {
    "builder": {
      "gc": {
        "enabled": true,
        "defaultKeepStorage": "10GB"
      }
    }
  }
  • Utilisez un cache externe avec registre et gérez la rétention là-bas.

Défaillance : invalidation du cache due aux permissions de fichiers ou aux métadonnées

Changer les permissions ou la propriété des fichiers dans le contexte de build peut invalider le cache pour les couches COPY, même si le contenu des fichiers est identique.

Détection :

  • Comparez les sommes de contrôle du contexte envoyé au builder. Utilisez docker build --progress=plain et regardez la taille de transferring context. Si elle diffère de manière inattendue, quelque chose a changé.

Récupération :

  • Utilisez .dockerignore pour exclure les fichiers non pertinents qui pourraient changer de permissions.
  • Normalisez les permissions avant le build à l'aide d'un script ou en CI.
  • Soyez cohérent dans la façon dont vous construisez le contexte de build.

Défaillance : montage de cache ne fonctionnant pas dans les builds multi-étapes

Les montages de cache sont limités à une seule étape sauf s'ils sont partagés. Si vous devez partager un montage de cache entre les étapes, vous devez le définir explicitement dans chaque étape.

Exemple :

# syntax=docker/dockerfile:1
FROM node:20-alpine AS deps
WORKDIR /app
COPY package.json yarn.lock ./
RUN --mount=type=cache,target=/root/.yarn yarn install --frozen-lockfile

FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN yarn build

Ici, le montage de cache n'est utilisé que dans l'étape deps. Si vous avez besoin du montage de cache dans l'étape builder également, vous définiriez un autre --mount là-bas.

Liste de contrôle des opérations

Utilisez cette liste de contrôle pour vous assurer que votre stratégie de mise en cache des couches est robuste et mesurable. Chaque élément comprend une commande de vérification et un signal attendu.

ÉlémentVérificationSignal attenduFréquence
BuildKit activédocker buildx lsBuilder actif avec pilote BuildKitUne fois par environnement
Le Dockerfile utilise des montages de cachegrep -n "RUN --mount=type=cache" DockerfileAu moins une correspondance pour l'installation des dépendancesChaque revue de Dockerfile
Images de base épingléesgrep -n "^FROM" DockerfileLes images incluent une empreinte ou une balise spécifiqueChaque revue de Dockerfile
.dockerignore existetest -f .dockerignore && echo OKOKChaque projet
Taille du cache sous contrôledocker system dfCache de build < 5 Go (ajustez à votre limite)Hebdomadaire
Nettoyage du cache planifiécrontab -l ou tâche CIExécute docker builder prune --filter until=168hHebdomadaire
Cache externe configuré (CI)docker buildx build --cache-from=type=registry,ref=... réussitLe journal de build montre CACHED pour la plupart des couchesChaque exécution CI
Gestion des secrets sûredocker build --secret id=mysecret,src=./secret.txt et inspecter l'image : docker history myappAucune chaîne de secret dans l'historiqueChaque build avec secrets

De plus, effectuez un test de redémarrage pour tout cache soutenu par un volume :

docker run -d --name cache-test -v cache-vol:/cache myimage sh -c "echo test > /cache/test && sleep 1000"
docker stop cache-test
docker start cache-test
docker exec cache-test cat /cache/test

Sortie attendue : test. Sinon, le montage du volume est mal configuré.

Conclusion

La mise en cache des couches Docker est une fonctionnalité puissante, mais ses concepts avancés nécessitent de la compréhension et une conception délibérée. En implémentant des montages de cache, en utilisant les fonctionnalités de BuildKit comme le cache externe et les secrets, et en vérifiant régulièrement le comportement du cache, vous pouvez obtenir des builds plus rapides et des pipelines plus fiables.

Commencez par une amélioration à faible risque : ajoutez un montage de cache à votre étape d'installation des dépendances. Exécutez le build deux fois et confirmez que le deuxième build affiche CACHED pour cette étape. Ensuite, explorez la mise en cache externe pour la CI. Observez toujours avant de changer et gardez des plans de récupération prêts pour les échecs de cache.

Un flux de travail technique fiable rend les échecs visibles, protège les valeurs sensibles, limite les changements à la ressource prévue et définit la vérification de récupération avant qu'un incident ne force la décision.

Recherches connexes

Score de qualité de l’article

Utilité pour le lecteur 100%
  • check_circle Guide prêt à lire
  • check_circle Exemples pratiques inclus
  • check_circle URL d’article optimisée pour le SEO