Passer au contenu principal

Layer Caching : optimiser vos builds Docker avec le cache des couches

Docker construit les images en couches (layers), chaque instruction du Dockerfile (COPY, RUN, etc.) crée une nouvelle couche.

Lors d’un build, Docker réutilise le cache pour une couche tant que cette couche et toutes les couches précédentes n’ont pas changé. En d’autres termes, le cache est linéaire : chaque instruction dépend du résultat de la précédente.

C’est ce mécanisme qui permet de gagner énormément de temps lors des builds incrémentaux.

Sans optimisation, cependant, ce processus peut devenir inefficace. Par exemple :

# ❌ Pas optimisé
COPY . .                           # Copie tout le code
RUN composer install --no-dev      # Installe toutes les dépendances

Si vous modifiez un seul fichier de code PHP, Docker doit :

  1. Recopier tous les fichiers (couche COPY invalidée).
  2. Réinstaller toutes les dépendances (couche RUN invalidée).
  3. Reconstruire toute l’image.

Résultat : builds longs et peu efficaces.

Pour y remédier, on utilise l’optimisation avec le Layer Caching. En copiant d’abord les fichiers de dépendances (composer.json et composer.lock) et en installant les dépendances avant de copier le reste du code, Docker ne reconstruit que les couches réellement affectées par vos modifications, ce qui accélère considérablement les builds.

# ✅ Optimisé
COPY composer.json composer.lock ./    # Copie uniquement les fichiers de dépendances
RUN composer install --no-dev          # Installe les dépendances
COPY . .                               # Copie le reste du code

L’avantage est immédiat : si vous ne modifiez que votre code source :

  1. La couche COPY composer.json composer.lock ./ reste en cache
  2. La couche RUN composer install reste en cache
  3. Seule la couche COPY . . est reconstruite

En pratique, pour optimiser un Dockerfile et tirer pleinement parti du cache des couches, commencez par copier les fichiers qui changent rarement, comme les fichiers de configuration et les fichiers de dépendances (composer.json, package.json, composer.lock). Ensuite, installez les dépendances, puis copiez enfin le reste du code source, qui évolue plus fréquemment.

Parallèlement, utilisez un fichier .dockerignore pour exclure les fichiers et dossiers inutiles (logs, caches, tests, dépendances locales, secrets). Cela réduit le contexte de build envoyé à Docker, évite d’invalider des couches inutilement et rend les builds incrémentaux encore plus rapides et fiables.

Cette combinaison permet à Docker de réutiliser un maximum de couches déjà construites, en ne reconstruisant que les parties réellement modifiées, et de garder vos images légères et efficaces.

# Couche 1: Base image
FROM php:8.4-apache

# Couche 2: Variables d'environnement
ENV APP_ENV=prod

# Couche 3: Copie des fichiers de dépendances
COPY composer.json composer.lock ./    # ← Change seulement si composer.json ou composer.lock change

# Couche 4: Installation des dépendances
RUN composer install --no-dev          # ← Change seulement si la couche 3 change

# Couche 5: Copie du code source
COPY . .                               # ← Change à chaque modification du code