Pourquoi le cache Docker est insuffisant pour un monorepo ?
Posté le 18 mars 2026 • 5 min de lecture • 997 motsLe cache Docker est puissant pour le packaging et la reproductibilité, mais il atteint rapidement ses limites dans un monorepo. Cet article explique pourquoi son modèle linéaire ne permet pas d’éviter le travail inutile, et pourquoi un cache plus granulaire devient indispensable.

Docker est partout.
Et avec lui, une idée largement répandue :
« Si on structure bien nos Dockerfiles, le cache Docker va accélérer notre CI. »
C’est vrai… mais seulement jusqu’à un certain point.
Dès qu’on travaille dans un monorepo — avec plusieurs projets, plusieurs langages, plusieurs pipelines logiques — le cache Docker montre rapidement ses limites.
Cet article explique pourquoi, sans dénigrer Docker, et surtout ce qu’il faut comprendre pour éviter de l’utiliser au mauvais endroit.
Commençons par être justes :
le cache Docker est excellent dans son domaine.
Docker met en cache :
layers) d’un DockerfileRUN, COPY, etc.) crée une coucheCela fonctionne très bien pour :
Docker excelle comme outil de packaging et de distribution.
Le cache Docker est basé sur une chaîne linéaire de couches.
Layer 1 → Layer 2 → Layer 3 → Layer 4
Si une couche change :
Exemple typique :
COPY package.json .
RUN pnpm install
COPY src/ ./src
RUN pnpm buildUn changement dans package.json invalide tout (ce qui est normal).
Mais un changement mineur dans src/ invalide aussi toute la fin, même si :
Docker ne sait pas faire autrement.
Un monorepo, ce n’est pas :
C’est :
Exemples :
Docker ne comprend pas ces frontières.
Pour Docker :
Résultat :
Les multi-stage builds sont souvent présentés comme la solution.
Ils permettent :
Exemple :
FROM node:20 AS deps
RUN pnpm install
FROM deps AS build
RUN pnpm build
FROM nginx AS runtime
COPY --from=build /dist /usr/share/nginx/htmlC’est une très bonne pratique.
Mais attention :
Les multi-stage builds optimisent le packaging, pas l’orchestration.
Docker BuildKit apporte des améliorations réelles :
Mais :
BuildKit accélère un modèle linéaire.
Il ne le transforme pas en modèle granulaire.
C’est le point clé.
Docker cache :
Mais dans un monorepo, on veut cacher :
Exemples de vraies unités de cache utiles :
Ces unités n’existent pas dans Docker.
Quand Docker est utilisé comme cache principal dans un monorepo, on observe souvent :
COPY fragmentés à l’extrêmeCe n’est pas un problème de compétence.
C’est un mauvais outil pour ce niveau d’abstraction.
Docker a parfaitement sa place dans un pipeline monorepo, mais pas comme moteur principal d’orchestration. Son rôle est d’assurer la reproductibilité et la portabilité des environnements.
Il excelle lorsqu’il s’agit d’installer des dépendances système, de construire des images fiables, de packager des artefacts finaux et de garantir une cohérence stricte entre la CI et la production.
En revanche, Docker n’est pas conçu pour décider quoi doit être reconstruit après un changement. Il ne comprend pas les frontières entre projets, ni les graphes de dépendances internes d’un monorepo. Son modèle repose sur des couches successives, pas sur des unités de travail indépendantes.
Autrement dit, Docker est un excellent outil de packaging et d’exécution, mais un mauvais outil d’orchestration. Dans un monorepo, il doit rester complémentaire : il exécute ce qui a été décidé ailleurs, mais ne devrait jamais être responsable de déterminer ce qui mérite d’être refait.
Le cache Docker n’est pas mauvais.
Il est insuffisant.
La règle simple à retenir
Docker sait “comment construire une image”.
Il ne sait pas “quel travail mérite d’être refait”.
Dans un monorepo, cette décision est centrale.
Pas parce qu’il est lent,
mais parce qu’il opère au mauvais niveau d’abstraction pour un monorepo.
Si ton pipeline cherche à :
Alors Docker ne peut pas être ton cache principal.
Il doit être complémentaire, pas central.