Docker Desktop vs Docker dans WSL : lequel est réellement plus rapide ?

Cet article vous a aidé ?

Si vos conteneurs donnent l’impression d’avancer dans du ciment mou sous Windows, vous ne vous faites pas d’illusions. L’écart de performances entre « Docker Desktop » et « Docker dans WSL » est réel — mais il est aussi souvent mal compris. La plupart des gens mesurent la mauvaise chose, puis « corrige » le problème en complexifiant leur configuration et rendant le débogage plus difficile.

Je vais vous dire ce qui est réellement plus rapide, pourquoi, et comment le prouver sur votre machine en moins d’une heure — sans appliquer des réglages par mimétisme dont vous ne vous souviendrez plus le trimestre suivant.

Ce que vous comparez vraiment (et pourquoi les noms sont trompeurs)

Sur Windows, le « produit » Docker et le « moteur » Docker se mélangent. Les gens disent « Docker Desktop est lent » quand ils veulent dire « mes montages bind sont lents ». Ou bien ils disent « Docker dans WSL est plus rapide » alors qu’ils ont accidentellement déplacé leur code dans un système de fichiers Linux et évité la taxe du système de fichiers Windows.

Définissons les deux configurations comme la performance les perçoit :

  • Docker Desktop : une application Windows qui exécute Docker Engine à l’intérieur d’une VM Linux. Sur les versions modernes, cette VM repose généralement sur WSL2. Desktop ajoute aussi des intégrations : interface, helpers d’identifiants, interconnexions réseau, chemins de partage de fichiers, extensions et réglages politiques.
  • Docker Engine dans WSL2 (« Docker dans WSL ») : vous installez et exécutez le Docker Engine Linux directement dans votre distribution WSL. Pas d’application Desktop requise. Les conteneurs s’exécutent dans le même environnement VM WSL2, mais vous gérez le démon comme sur un système Linux classique.

Remarquez ce qui manque : le runtime du conteneur ne change pas magiquement. Les deux finissent dans un contexte noyau Linux (la VM WSL2). La différence est où réside votre démon, comment le partage de fichiers est câblé, et combien de couches de traduction vous ajoutez par accident.

Voici la manière la plus rapide d’y penser :

  • Si votre charge est liée au CPU (compilation, compression, crypto), Desktop vs Engine WSL est généralement une différence marginale.
  • Si votre charge est liée au système de fichiers (installations Node.js, hot reloaders, serveurs de langage, grands monorepos), l’emplacement des fichiers et le type de montage dominent tout.
  • Si votre charge est liée au réseau (beaucoup de services localhost, proxies, VPN), les détails d’intégration et les chemins NAT peuvent rendre l’un « aléatoirement » pire.

Une citation, parce qu’elle colle : Werner Vogels a une idée « paraphrasée » selon laquelle tout échoue, tout le temps — donc on conçoit et on opère en supposant l’échec. Le travail sur les performances est similaire : supposez que votre chemin le plus rapide se dégradera à moins de le garder simple et observable.

Blague n°1 : mesurer Docker sur Windows sans vérifier où se trouve votre code, c’est comme chronométrer une voiture de sport avec le frein à main tiré. Vous obtiendrez un chiffre, certes.

Quelques faits et contexte historique utilisables dans les débats

Ce ne sont pas des anecdotes de quiz. Ils expliquent pourquoi le profil de performance ressemble à ce qu’il est.

  1. Docker sur Windows s’appuyait initialement fortement sur Hyper-V pour exécuter une VM Linux, car les conteneurs ont besoin d’un noyau Linux. Les configurations anciennes imposaient un overhead notable et un réseau fragile.
  2. WSL1 n’était pas une VM ; il traduisait les appels système Linux en comportements Windows. C’était ingénieux, mais ce n’était pas un « vrai Linux », et de nombreux comportements de conteneurs étaient maladroits ou impossibles.
  3. WSL2 est passé à un vrai noyau Linux dans une VM légère, ce qui a rendu les charges de travail de conteneurs Linux beaucoup plus compatibles — et souvent plus rapides pour les opérations natives du système de fichiers Linux.
  4. Les problèmes de performances de fichiers proviennent souvent de la traversée de la frontière Windows/Linux (par ex. accès à /mnt/c depuis Linux). Cette frontière doit traduire métadonnées, permissions et sémantiques de notifications.
  5. Les montages bind ne sont pas intrinsèquement lents ; les montages bind qui traversent une frontière de virtualisation le sont. Un montage bind Linux à l’intérieur du système de fichiers Linux est typiquement correct.
  6. Docker Desktop a évolué en plateforme, pas seulement en lanceur de démon. Les fonctionnalités supplémentaires sont utiles, mais elles ajoutent des pièces mobiles qui peuvent impacter les performances et le débogage.
  7. BuildKit a changé les caractéristiques de performance des builds Docker en améliorant le caching, le parallélisme et les étapes de build basées sur des montages. Mais il a aussi rendu certains goulots d’étranglement sur le système de fichiers plus visibles.
  8. Les notifications de changement de fichiers sous Windows diffèrent de Linux dans des cas limites ; les piles de hot reload peuvent se comporter différemment selon que les événements sont transmis ou sondés.

D’où vient réellement la vitesse : CPU, disque, montages et réseau

CPU : généralement pas le facteur déterminant

Les charges CPU-bound (builds Go/Rust, gzip, runners de tests qui n’écrasent pas le disque) tendent à performer de manière similaire entre Desktop et Engine WSL car les deux s’exécutent dans le même environnement Linux soutenu par WSL2 dans de nombreuses configurations modernes. La frontière VM existe dans les deux cas. La question devient : avez-vous accidentellement ajouté des couches supplémentaires (comme exécuter Docker Desktop tout en appelant des chemins Windows avec des montages bind lourds) ?

I/O disque : là où la plupart des gens perdent la semaine

Le levier de vitesse unique le plus important pour le dev Docker sur Windows est où résident vos fichiers de projet et comment ils sont montés.

  • Meilleur cas : le code est stocké à l’intérieur du système de fichiers Linux de WSL2 (le ext4 de votre distro dans un VHDX), et les conteneurs utilisent des volumes ou des montages bind qui restent dans Linux. Métadonnées rapides, opérations sur petits fichiers rapides.
  • Pire cas : le code est stocké sur NTFS (par ex. C:\src) et vous le montez dans les conteneurs via la frontière (/mnt/c/src ou partage Desktop). Les charges axées sur les petits fichiers sont fortement pénalisées.

Pourquoi ? Parce qu’une opération « simple » comme « stat 30 000 fichiers » devient une fête de la traduction : mappage des métadonnées, mappage des permissions, bizarreries de sensibilité à la casse, et invalidations de cache. node’s node_modules est essentiellement un test de torture pour petits fichiers. Les virtualenvs Python et les registres cargo Rust le sont aussi.

Montages bind vs volumes : votre contrat de performance caché

Volumes vivent dans le backend de stockage Linux de Docker (overlay2 sur ext4 dans WSL2). Ils sont généralement rapides et prévisibles. Les montages bind reflètent un chemin hôte dans le conteneur. Si ce chemin est sur Windows, vous payez la traversée de frontière. Si ce chemin est à l’intérieur de la distro WSL2, les montages bind peuvent être acceptables.

Traduit en conseil : gardez vos dépendances dans Linux (volumes) même si votre source doit rester sur Windows. Ou mieux : gardez les deux dans Linux et utilisez l’intégration d’éditeur pour travailler avec les chemins WSL.

Réseau : globalement correct jusqu’à ce que VPN et localhost interviennent

WSL2 utilise un réseau virtualisé NAT. Docker ajoute sa propre plomberie réseau virtuelle. Docker Desktop ajoute davantage d’intégration pour que localhost se comporte comme attendu sur Windows.

Les problèmes de performance réseau apparaissent généralement comme :

  • pics de latence mystérieux lorsque qu’un VPN d’entreprise est connecté
  • retards de résolution DNS à l’intérieur des conteneurs
  • incohérences de redirection de ports entre Windows ↔ WSL ↔ conteneur

Desktop a tendance à « juste fonctionner » plus souvent pour publier des ports vers Windows. WSL Engine peut être plus propre pour des maillages de services Linux-to-Linux à l’intérieur de WSL, mais vous devrez peut-être fournir plus de travail manuel pour que les outils Windows voient les services.

Mémoire et cache de pages : la raison discrète pour laquelle une configuration « semble » plus rapide

Le cache de pages Linux est une superpuissance pour les performances. Si votre charge relit fréquemment les mêmes arbres de dépendances, le cache aide beaucoup. Mais le comportement mémoire de WSL2 (allocation dynamique et reclaim) peut rendre la performance incohérente si la VM est à court de ressources ou est en train de ballonner constamment. Desktop ajoute ses propres limites de ressources et réglages UI, qui peuvent être utiles — ou vous brider si réglés trop bas.

Qui est plus rapide selon le cas : une matrice de décision franche

Il n’existe pas un « plus rapide » universel. Il existe un plus rapide selon votre goulot. Voici la prise pratique.

Si vous voulez la vitesse maximale pour du dev intensif sur le système de fichiers

Choisissez Docker Engine dans WSL2, et gardez vos dépôts dans le système de fichiers WSL (\\wsl$ depuis Windows ; stockage réel sous le VHDX de la distro). Utilisez des outils natifs Linux. Montez depuis des chemins Linux, pas depuis /mnt/c.

Si vous voulez l’expérience développeur la plus prédictible dans une équipe Windows mixte

Choisissez Docker Desktop, surtout si vous avez besoin d’une gestion GUI, de helpers d’identifiants, de proxies d’entreprise, de bascules Kubernetes, ou de moins de tickets « pourquoi localhost ne marche pas ». Mais toujours : conservez votre projet dans WSL si la vitesse vous importe.

Si votre goulot est les builds, pas le live-reload

Les deux configurations peuvent être rapides. Ce qui compte, c’est BuildKit, la stratégie de cache, et éviter les invalidations inutiles (copier tout le repo trop tôt dans le Dockerfile, ou reconstruire les dépendances à chaque modification).

Si vous êtes sur un VPN d’entreprise qui casse le DNS

Desktop offre souvent de meilleurs réglages et intégrations. WSL Engine peut être « plus pur » mais vous obligera peut-être à déboguer resolv.conf et le proxy DNS Windows à 16h55.

Blague n°2 : rien n’accélère une réunion « optimisons Docker » comme quelqu’un qui dit « ça marche sur mon laptop ». Soudain, tous les laptops deviennent des preuves.

Tâches pratiques : commandes, sorties attendues et décision à prendre

Voici des vérifications réelles que j’exécuterais avant de croire le benchmark de quiconque. Chaque tâche inclut : commande, ce que la sortie signifie, et la suite à donner.

Task 1: Confirm where Docker is running (Desktop vs WSL Engine)

cr0x@server:~$ docker context ls
NAME                DESCRIPTION                               DOCKER ENDPOINT                             ERROR
default *           Current DOCKER_HOST based configuration   unix:///var/run/docker.sock
desktop-linux       Docker Desktop                            unix:///var/run/docker.sock

Signification : Les contexts vous indiquent quel démon vous interrogez. Si vous voyez desktop-linux, vous utilisez probablement l’intégration du démon Desktop.

Décision : Si vous comparez, changez explicitement de contexte et relancez les tests. Ne « pensez » pas que vous avez changé ; prouvez-le.

Task 2: Identify the daemon and storage driver

cr0x@server:~$ docker info --format '{{.ServerVersion}} {{.Driver}} {{.OperatingSystem}}'
27.3.1 overlay2 Docker Desktop

Signification : Overlay2 sur Linux est typique. Si vous ne voyez pas overlay2, quelque chose d’inhabituel se produit. Si ce n’est pas Linux, vous n’êtes pas sur le chemin attendu.

Décision : Si le driver de stockage est inattendu, arrêtez. Votre investigation de performance sera fictive tant que vous n’aurez pas corrigé cela.

Task 3: Measure whether your project is on Windows or WSL filesystem

cr0x@server:~$ pwd
/mnt/c/src/myapp

Signification : /mnt/c est NTFS Windows monté dans WSL. Si votre projet est ici et que vous le montez en bind, vous payez probablement la taxe de frontière.

Décision : Si la vitesse vous importe, déplacez le repo dans Linux (par ex. ~/src/myapp dans WSL) et retestez avant de changer autre chose.

Task 4: Compare metadata-heavy ops (the “node_modules test” without installing anything)

cr0x@server:~$ time find . -type f | wc -l
48219

real    0m3.214s
user    0m0.112s
sys     0m0.988s

Signification : Ceci approximativement le coût de traversée de petits fichiers. Sur /mnt/c, cela peut être dramatiquement plus lent que dans Linux.

Décision : Si le temps sys est élevé et que le real est bien plus grand que prévu, votre goulot est la traduction du système de fichiers. Corrigez l’emplacement/les montages, pas le CPU.

Task 5: Compare bind mount performance inside a container

cr0x@server:~$ docker run --rm -v "$PWD":/work -w /work alpine sh -lc 'time find . -type f >/dev/null'
real    0m4.02s
user    0m0.07s
sys     0m1.21s

Signification : Cela mesure le chemin du montage bind depuis la vue du conteneur. S’il est bien plus lent que d’exécuter find sur l’hôte, le pont de montage est le coupable.

Décision : Si lent, passez au repo côté Linux ou utilisez des volumes Docker pour les répertoires lourds en dépendances.

Task 6: Confirm whether your container writes are going to a volume or a bind mount

cr0x@server:~$ docker inspect -f '{{range .Mounts}}{{.Type}} {{.Source}} -> {{.Destination}}{{"\n"}}{{end}}' myapp
bind /mnt/c/src/myapp -> /app
volume myapp_node_modules -> /app/node_modules

Signification : Une configuration hybride est souvent la meilleure : source via bind mount, dépendances via volume.

Décision : Si node_modules ou target ou .venv vit sur un montage bind backé par Windows, déplacez-le dans un volume.

Task 7: Check WSL version and distro state (from within WSL)

cr0x@server:~$ wsl.exe -l -v
  NAME            STATE           VERSION
* Ubuntu-22.04    Running         2

Signification : Vous voulez WSL2 pour les performances et la compatibilité noyau. WSL1 est une autre bête.

Décision : Si vous êtes sur WSL1, migrez. Ne tentez pas de tuner autour.

Task 8: Check whether Docker Desktop is the daemon you’re talking to (WSL integration can blur it)

cr0x@server:~$ ps -ef | grep -E 'dockerd|containerd' | grep -v grep
root        2660       1  0 10:14 ?        00:00:02 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

Signification : Si vous voyez dockerd tournant dans la distro WSL, vous exécutez probablement l’Engine dans WSL. Sinon, vous utilisez peut-être l’intégration de socket de Desktop.

Décision : Décidez qui possède le démon : Desktop ou systemd dans WSL. Évitez la propriété à moitié-si-mi-si-si pour un débogage prévisible.

Task 9: Check systemd state in WSL (relevant for running Docker Engine properly)

cr0x@server:~$ ps -p 1 -o comm=
systemd

Signification : Si le PID 1 est systemd, vous pouvez gérer Docker comme un service Linux normal. Sinon, vous utilisez peut-être des méthodes d’init alternatives.

Décision : Si vous voulez la stabilité de l’Engine WSL, activez systemd et exécutez Docker sous celui-ci.

Task 10: Measure build performance (BuildKit on, cache working)

cr0x@server:~$ DOCKER_BUILDKIT=1 docker build -t myapp:bench .
[+] Building 18.2s (12/12) FINISHED
 => [internal] load build definition from Dockerfile                                      0.0s
 => => transferring dockerfile: 1.23kB                                                    0.0s
 => [internal] load metadata for docker.io/library/node:20-alpine                         0.8s
 => [1/6] FROM docker.io/library/node:20-alpine@sha256:...                                0.0s
 => [internal] load .dockerignore                                                         0.0s
 => => transferring context: 2.31kB                                                       0.0s
 => [2/6] WORKDIR /app                                                                    0.1s
 => [3/6] COPY package*.json ./                                                           0.1s
 => [4/6] RUN npm ci                                                                      14.9s
 => [5/6] COPY . .                                                                        1.5s
 => [6/6] RUN npm test                                                                    0.8s
 => exporting to image                                                                    0.0s

Signification : L’étape lente est évidente. Si COPY . . est lent, votre transfert de contexte et le chemin du système de fichiers sont mauvais. Si npm ci est lent, vous êtes lié par l’I/O ou le réseau.

Décision : Si COPY est lent, corrigez l’emplacement du repo et le .dockerignore. Si l’installation des dépendances est lente, déplacez les répertoires de cache vers des volumes et assurez-vous que votre DNS/proxy ne bride pas.

Task 11: Observe container CPU throttling or host contention

cr0x@server:~$ docker stats --no-stream
CONTAINER ID   NAME        CPU %     MEM USAGE / LIMIT     MEM %     NET I/O       BLOCK I/O      PIDS
c3a1d2e9f0b1   myapp       225.41%   612.3MiB / 7.6GiB     7.86%     12.4MB / 9MB  1.2GB / 38MB  34

Signification : Si le CPU est saturé et que vous êtes toujours lent, vous pouvez être lié au calcul, ou vous êtes bridé par le nombre de CPUs alloués.

Décision : Si le CPU est élevé et que les étapes de build sont gourmandes en calcul, allouez plus de CPU/mémoire à WSL2/Desktop ou réduisez le parallélisme dans les toolchains.

Task 12: Check disk usage and where Docker stores its data

cr0x@server:~$ docker system df
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          27        6         9.812GB   5.104GB (52%)
Containers      14        2         1.102GB   812.4MB (73%)
Local Volumes   19        7         22.44GB   8.201GB (36%)
Build Cache     45        0         3.993GB   3.993GB

Signification : L’encombrement des volumes et du cache de build peut se transformer en « mon disque est lent » parce que votre VHDX s’agrandit et que le disque hôte est fragmenté ou sous pression.

Décision : Si la part reclaimable est élevée, nettoyez le cache de build/les volumes inutilisés. Si le disque hôte est presque plein, cessez de prétendre que c’est un problème Docker.

Task 13: Check DNS latency inside containers (network “slow” often means DNS “slow”)

cr0x@server:~$ docker run --rm alpine sh -lc 'time nslookup registry-1.docker.io >/dev/null'
real    0m0.42s
user    0m0.01s
sys     0m0.01s

Signification : Si le DNS prend des secondes, les installations de paquets et les pulls vont ramer. Les VPNs et split-DNS peuvent déclencher cela.

Décision : Si lent, concentrez-vous sur la configuration DNS (comportement de resolv.conf dans WSL, réglages de proxy DNS de Desktop, règles DNS d’entreprise), pas sur des flags Docker.

Task 14: Measure bind mount event behavior for hot reloaders (inotify vs polling)

cr0x@server:~$ docker run --rm -v "$PWD":/work -w /work alpine sh -lc 'apk add --no-cache inotify-tools >/dev/null && inotifywait -t 2 -e modify . || echo timeout'
Setting up watches.
Watches established.
timeout

Signification : Si vous n’obtenez pas les événements de façon fiable, votre outil de hot reload peut basculer en polling, ce qui consomme le CPU et « donne l’impression » d’être lent.

Décision : Si les événements ne traversent pas votre montage, déplacez le code dans le système de fichiers WSL ou configurez l’outil pour utiliser le polling avec des intervalles raisonnables (en acceptant le coût CPU).

Playbook de diagnostic rapide (premières/deuxièmes/troisièmes vérifications)

Ceci est l’ordre qui trouve le goulot le plus rapidement dans les équipes réelles. Pas de la théorie. Triage.

First: identify the boundary you’re crossing

  • Est-ce que votre repo est sous /mnt/c ?
  • Montez-vous des chemins Windows en bind dans des conteneurs ?
  • Vos répertoires de dépendances vivent-ils sur des montages backés par Windows ?

Si oui : attendez-vous à des opérations métadonnées lentes. Corrigez l’emplacement/stratégie de montage avant de toucher à autre chose.

Second: decide who owns the daemon and keep it consistent

  • Utilisez-vous le démon de Docker Desktop via l’intégration, ou un dockerd que vous lancez dans WSL ?
  • Avez-vous les deux installés et basculez-vous parfois sans vous en rendre compte ?

Si incohérent : vos mesures varieront. Choisissez-en un, documentez-le, et imposez-le avec des contexts ou des scripts d’équipe.

Third: isolate build vs runtime vs network

  • Build lent ? Inspectez la sortie de docker build : est-ce COPY, des installations de dépendances, ou des tests ?
  • Runtime lent ? Vérifiez docker stats, les schémas d’écriture disque, et le comportement des événements du système de fichiers.
  • Pull/install lent ? Vérifiez la latence DNS et le comportement du VPN/proxy.

Fourth: check resource caps and host contention

  • WSL/Desktop est-il limité à 2 CPU et 2 Go de RAM parce que quelqu’un « a optimisé » ?
  • Le disque hôte est-il presque plein ou sous un scan antivirus intensif ?

Si oui : vous ne tunez pas Docker, vous tunez l’environnement hôte.

Trois mini-récits d’entreprise depuis le terrain

Incident : la fausse hypothèse « WSL = vitesse Linux »

Une entreprise de taille moyenne a déployé des laptops Windows pour une équipe de dev qui utilisait auparavant des postes Linux. Le plan était simple : « Utilisez WSL2, exécutez Docker, tout redevient essentiellement Linux ». La première semaine, les ingénieurs se sont plaints que les tests et installations de dépendances étaient douloureusement lents, mais seulement pour certains repos.

L’équipe a supposé que le problème venait de l’overhead de Docker Desktop et a commencé à désinstaller Desktop, passer au Docker Engine dans WSL, et ajuster des flags du démon. Ça s’est amélioré… légèrement. Pas convenablement.

Le vrai coupable était banal : les repos vivaient sur C:\ parce que les politiques de sauvegarde et de protection des endpoints de l’entreprise étaient liées aux chemins Windows. Les devs éditaient le code dans des outils Windows, et WSL accédait via /mnt/c. Leurs montages bind traversaient la frontière, et la charge était une tempête parfaite d’opérations métadonnées sur petits fichiers.

La correction n’a pas été « changer Docker ». C’était une exception de politique et un changement de workflow : conserver les repos dans WSL pour le développement actif, garder les artefacts exportés sur Windows, et utiliser l’intégration IDE WSL. La même configuration Docker a soudainement paru « plus rapide » parce que le système de fichiers a cessé d’être un traducteur pour chaque appel système.

Optimisation qui s’est retournée contre eux : affamer la VM pour « économiser la batterie »

Une autre équipe voulait des laptops qui chauffent moins en déplacement. Quelqu’un a décidé de brider les ressources WSL2/Docker : moins de CPU, peu de mémoire, reclaim agressif. Sur le papier, ça a réduit le bruit des ventilateurs. En pratique, ça a transformé les builds en machine à sous.

Les symptômes étaient étranges : le premier build après un reboot allait bien, le deuxième ruminait, puis ça s’améliorait, puis ça bloquait à nouveau. Les ingénieurs ont d’abord accusé les caches, puis Docker, puis les branches de chacun. Classique.

Le comportement caché était la pression mémoire. Avec trop peu de RAM, le cache de pages Linux ne pouvait pas faire son travail. Pendant ce temps, des compilations répétées et des scans de dépendances remuaient le cache du système de fichiers et déclenchaient un comportement proche du swap à l’intérieur de la VM. Les limites CPU amplifiaient la douleur : moins de parallélisme, temps mur plus long, plus de temps pour que les processus d’arrière-plan entrent en collision.

Ils sont revenus à des limites sensées, puis ont rendu les économies de batterie explicites et optionnelles. Morale : une « optimisation » qui retire de la marge crée de la gigue, et la gigue est ce qui fait que les ingénieurs se méfient de chaque autre métrique.

Pratique ennuyeuse mais correcte qui a sauvé la mise : normaliser le workflow et mesurer une chose à la fois

Une grande organisation avait un mix d’utilisateurs Desktop et d’utilisateurs Engine WSL. Les plaintes sur les performances arrivaient en continu, mais chaque ticket était inutilisable : « Docker est lent ». Très aidant.

Un ingénieur orienté SRE a créé un court « contrat Docker sur Windows » interne : où placent les repos, quel démon est standard, comment monter les dépendances, et un script de benchmark minimal qui mesure séparément la traversée de fichiers, le temps de build et la latence DNS. Ce n’était pas glamour. C’était une checklist.

Quand un incident digne d’alerte est survenu — les devs ne pouvaient pas tirer des images et les pipelines ralentissaient — l’équipe a utilisé le script et a immédiatement constaté des pics de latence DNS à l’intérieur des conteneurs. Cela pointait vers un changement DNS d’entreprise interagissant avec le split tunneling VPN. Sans les tests de base, ils auraient perdu des jours à « tuner Docker ».

Ils ont résolu la politique DNS, pas Docker. La pratique ennuyeuse : cohérence et discipline de mesure, et elle a payé dès la première vraie panne à grande échelle.

Erreurs courantes : symptôme → cause racine → correction

1) « npm install prend une éternité dans les conteneurs »

Symptôme : les installations de dépendances sont 5–20× plus lentes que prévu ; le CPU est bas ; l’activité disque est constante.

Cause racine : les dépendances sont écrites sur un montage bind backé par Windows (/mnt/c), provoquant des opérations métadonnées lentes.

Correction : stockez le repo dans le système de fichiers WSL, ou gardez node_modules dans un volume Docker et montez uniquement le code source.

2) « Le hot reload ne se déclenche pas, le serveur de dev poll et brûle le CPU »

Symptôme : les changements de fichiers ne se propagent parfois pas ; les ventilateurs tournent ; le reload est retardé.

Cause racine : les événements inotify ne traversent pas proprement certains chemins de montage ; l’outil bascule en polling.

Correction : déplacez le repo dans le système de fichiers WSL ; configurez le watcher pour utiliser le polling avec des intervalles raisonnables si vous devez rester sur des chemins Windows.

3) « Docker build est lent au niveau de COPY »

Symptôme : COPY . . prend des secondes à des minutes ; le transfert de contexte est lourd.

Cause racine : contexte de build massif dû à un mauvais .dockerignore ; repo sur chemin Windows ; beaucoup de petits fichiers.

Correction : améliorez le .dockerignore ; relocalisez le repo ; réordonnez le Dockerfile pour maximiser le cache (copiez d’abord les manifests, puis installez, puis copiez le source).

4) « Les pulls et apt install se bloquent aléatoirement sur le VPN »

Symptôme : les pulls d’images se figent ; les installations de paquets attendent la résolution de noms.

Cause racine : DNS à l’intérieur des conteneurs lent ou cassé à cause du split-DNS VPN et du NAT.

Correction : mesurez la latence DNS ; ajustez la configuration DNS pour WSL/Desktop ; coordonnez avec l’informatique pour un résolveur correct.

5) « C’est rapide pour moi mais lent pour les nouveaux arrivants »

Symptôme : certaines machines vont bien, d’autres sont désastreuses, même repo.

Cause racine : propriété du démon incohérente (Desktop vs Engine WSL), emplacements de fichiers inconsistants, limites de ressources différentes.

Correction : standardisez : une configuration supportée, une recommandation d’emplacement de repo, un script de diagnostic de référence.

6) « L’espace disque disparaît et tout ralentit avec le temps »

Symptôme : les builds ralentissent ; disque presque plein ; Docker rapporte beaucoup de données reclaimables.

Cause racine : le cache de build et les volumes gonflent ; le VHDX WSL s’agrandit ; la pression disque hôte augmente.

Correction : nettoyez les images/volumes/caches de build inutilisés ; surveillez le disque hôte ; évitez de conserver indéfiniment d’anciennes couches localement.

Listes de vérification / plan étape par étape

Plan A : vous voulez la boucle de dev la plus rapide sur Windows

  1. Déplacez les repos actifs dans le système de fichiers WSL : ~/src dans votre distro.
  2. Utilisez le support IDE pour WSL afin que l’édition reste naturelle.
  3. Utilisez Docker Engine dans WSL2 si vous voulez des couches minimales, ou Desktop si vous avez besoin d’intégration compatible entreprise — mais gardez les fichiers dans WSL dans les deux cas.
  4. Montez la source via un chemin Linux. Gardez les répertoires de dépendances dans des volumes.
  5. Mesurez : temps de traversée de fichiers, temps de traversée depuis un conteneur monté, durées des étapes de build, latence DNS.

Plan B : vous devez garder le code sur C:\ pour des raisons d’entreprise

  1. Acceptez que /mnt/c soit plus lent pour les petits fichiers. Ne combattez pas la physique avec des messages Slack.
  2. Utilisez des volumes pour les répertoires lourds en dépendances : node_modules, .venv, target, vendor, caches d’outils.
  3. Réglez le comportement des watchers : préférez le polling avec des intervalles raisonnables plutôt que d’« espérer » qu’inotify fonctionne.
  4. Améliorez le .dockerignore pour réduire le transfert de contexte.
  5. Surveillez les exceptions antivirus/endpoint (avec approbation sécurité). Ces scanners adorent mâcher les arbres de dépendances.

Plan C : vous optimisez les builds, pas le dev en live

  1. Activez BuildKit ; confirmez que le cache fonctionne.
  2. Réordonnez le Dockerfile pour des hits de cache : copiez d’abord les lockfiles, installez les deps, puis copiez le source.
  3. Minimisez le contexte de build avec .dockerignore.
  4. Séparez les problèmes réseau des problèmes disque avec un test de timing DNS.
  5. Utilisez des builds multi-étapes quand cela réduit la taille finale sans augmenter le temps de rebuild.

FAQ

1) Docker Desktop est-il toujours plus lent que Docker Engine dans WSL2 ?

Non. Pour les charges CPU-bound, ils sont souvent similaires. Les gains importants viennent généralement de garder les fichiers dans le système de fichiers WSL et d’éviter les montages bind backés par Windows.

2) Quelle est la seule amélioration de performance la plus importante ?

Déplacez votre repo depuis C:\ (accédé comme /mnt/c) vers le système de fichiers de la distro WSL, puis montez depuis là. Cela retire une couche de traduction sur les chemins chauds.

3) Pourquoi les montages bind sont-ils lents sur Windows ?

Les montages bind qui traversent la frontière Windows ↔ Linux doivent traduire la sémantique du système de fichiers. Les opérations métadonnées sur petits fichiers deviennent coûteuses. Les volumes contournent cela en restant dans le stockage Linux.

4) Puis-je continuer à utiliser des éditeurs Windows si mon repo est dans WSL ?

Oui. La plupart des éditeurs modernes ont une intégration WSL. L’essentiel : stockez les fichiers dans Linux, éditez via un pont conçu pour cela, et laissez les conteneurs y accéder sans traverser NTFS.

5) Dois-je désinstaller Docker Desktop si j’exécute Docker Engine dans WSL ?

Si vous n’avez pas besoin des fonctionnalités Desktop, le désinstaller peut réduire la confusion et la complexité en arrière-plan. Si votre organisation dépend de l’intégration Desktop (proxies, magasin d’identifiants, support), conservez-le — mais soyez explicite sur le démon utilisé.

6) Pourquoi mes performances changent-elles après reboot ou veille ?

Le cycle de vie de la VM WSL2, la chaleur du cache de pages et l’allocation mémoire dynamique influencent la « sensation ». Les caches froids rendent tout plus lent. Les limites de ressources peuvent rendre le comportement incohérent.

7) Kubernetes dans Docker Desktop est-il un problème de performances ?

Ça peut l’être, principalement en consommant CPU/RAM et en ajoutant du churn en arrière-plan. Si vous ne l’utilisez pas, désactivez-le. Si vous l’utilisez, budgetez les ressources comme un système adulte, pas comme une démo.

8) Les volumes Docker sont-ils toujours plus rapides que les montages bind ?

Pas toujours. Les volumes sont généralement plus rapides que les montages bind backés par Windows. Mais un montage bind à l’intérieur du système de fichiers WSL peut être tout à fait acceptable et plus pratique pour le workflow dev.

9) Comment savoir si le goulot est le DNS ?

Chronométrez un nslookup à l’intérieur d’un conteneur. Si cela prend des secondes, vos « pulls lents » et « installs lentes » sont probablement dues à des problèmes de résolveur/VPN/proxy.

10) Et si mon équipe utilise Compose et que c’est lent ?

Compose amplifie les problèmes de système de fichiers et de watch car il monte souvent plusieurs services depuis le même repo. Corrigez d’abord les montages et l’emplacement des fichiers, puis examinez l’utilisation de ressources par service.

Prochaines étapes réalisables cette semaine

  1. Choisissez une base : décidez si votre standard est Docker Desktop ou WSL Engine. Standardisez les contexts et scripts pour que personne ne « compare accidentellement » des démons différents.
  2. Déplacez un repo dans WSL et relancez deux mesures : temps de traversée find sur l’hôte et dans un conteneur monté en bind. Si vous voyez une grosse baisse, vous avez trouvé votre levier principal.
  3. Corrigez les montages stratégiquement : gardez la source éditable, mais placez les arbres de dépendances dans des volumes. C’est le meilleur compromis quand la politique impose des chemins Windows.
  4. Exécutez le playbook de diagnostic rapide sur la prochaine plainte « Docker est lent ». Si vous ne pouvez pas dire si c’est le système de fichiers, le DNS ou les limites de ressources, vous ne diagnostiquez pas — vous vous contentez de narrer.
  5. Documentez les règles ennuyeuses (emplacement des repos, montages, vérification DNS, hygiène du cache de build). C’est ainsi que vous évitez de répéter la même investigation à chaque onboarding.

Si vous voulez une recommandation unique et opinionnée : placez votre code dans le système de fichiers Linux de WSL2 et arrêtez de monter NTFS dans des conteneurs sauf si c’est indispensable. Docker Desktop vs WSL Engine est secondaire ; la frontière du système de fichiers est le boss final.

← Précédent
Observateur d’événements pour les humains : trouver les erreurs réelles en 5 minutes
Suivant →
Installation Ubuntu Server 24.04 LTS : la configuration minimale réellement sécurisée

Laisser un commentaire