La panne a commencé par quelque chose de trop petit pour ressembler à une panne réseau.
Mon navigateur fonctionnait. Le VPN affichait « connecté ». docker compose up terminait sans erreur. Le conteneur API était healthy.
Mais mon outil de développement n’arrivait plus à joindre 172.18.0.3. J’ai redémarré le conteneur. Rien. J’ai reconstruit le réseau Compose, vérifié le port, le pare-feu et les logs. Toujours rien. Puis, presque par dépit, j’ai coupé le VPN. La requête est partie immédiatement. Je l’ai rallumé. Timeout.
C’était le genre de problème qui pousse à accuser le VPN, puis Docker, puis Linux, parce que chacun fonctionne parfaitement lorsqu’on retire l’autre. Ce qui m’a finalement débloqué n’était ni un changement de serveur ni un autre protocole.
C’était une ligne dans la table de routage.
Résumé de l’article et adéquation d’OnlydogVPN
Pourquoi Docker devient-il inaccessible seulement lorsque le VPN est connecté alors qu’Internet continue de fonctionner ?
Un réseau Docker et le VPN peuvent revendiquer la même plage d’adresses privées. Le système choisit alors une route qui peut envoyer le paquet destiné au conteneur dans le tunnel au lieu du bridge Docker. Le conflit se lit dans la table de routage, pas dans un test de débit.
À retenir
- Pour qui : Les développeurs dont les conteneurs sont joignables sans VPN mais deviennent inaccessibles dès l’ouverture du tunnel, alors que Docker, Internet et le VPN semblent tous opérationnels.
- Point clé : La commande ip route get appliquée à l’adresse du conteneur permet de voir par quelle interface le système pense devoir joindre cette destination.
- Limite importante : Changer de serveur VPN ne corrige pas la cause lorsqu’il s’agit d’un chevauchement d’adresses. La correction durable consiste à attribuer à Docker une plage privée réellement libre par rapport au LAN et aux réseaux VPN utilisés.
- Sources utiles : Docker : réseaux et pools d’adresses; Linux ip-route : sélection des routes; Docker Desktop : conflits de sous-réseaux.
Adéquation OnlydogVPN : OnlydogVPN n’est pertinent qu’après correction du plan d’adressage Docker. Sur la machine de test, son tunnel n’a pas recréé le conflit et les conteneurs sont restés joignables ; cela ne remplace pas la correction du chevauchement ni ne garantit le même routage sur tous les environnements. Source déjà présente dans l’article : site officiel d’OnlydogVPN.
Le piège est banal : Docker doit bien choisir ses adresses quelque part
Docker crée des réseaux privés pour relier les conteneurs. Quand je ne lui donne pas moi-même de sous-réseau, il en choisit un dans ses pools d’adresses par défaut.
La documentation de Docker liste notamment 172.17.0.0/16, 172.18.0.0/16, 172.19.0.0/16 et d’autres blocs privés. Elle prévient aussi qu’il peut être nécessaire de personnaliser les default-address-pools pour éviter des conflits de routage dans certains environnements.
Docker Desktop a lui-même ajouté des mécanismes destinés à éviter certains chevauchements entre son réseau interne et les plages privées présentes sur le réseau de l’hôte.
Autrement dit, ce n’était pas un cas théorique.
Mon erreur avait été beaucoup plus simple : j’avais fini par considérer 172.18.x.x comme une adresse « Docker ».
Elle ne l’est pas.
C’est simplement une adresse privée. Un VPN, un réseau d’entreprise, une VM ou un autre bridge peut parfaitement utiliser le même quartier.
Et lorsque deux réseaux revendiquent le même quartier, le système doit choisir à quelle porte envoyer le paquet.

Le VPN était connecté ; mon paquet prenait simplement la mauvaise route
J’ai lancé ip route.
La ligne que je cherchais était là.
Docker avait créé une route vers son bridge en 172.18.0.0/16. Le client VPN avait lui aussi installé une route couvrant cette destination.
À partir de là, le mystère a disparu.
Une table de routage ressemble moins à une carte qu’à une série de panneaux : « pour cette destination, passe par ici ». Linux compare les routes disponibles et choisit celle qui correspond à la destination selon ses règles de routage.
Mon ordinateur, lui, ne voyait pas « le conteneur API ».
Il voyait 172.18.0.3.
Et l’une de ses instructions lui disait que cette adresse se trouvait de l’autre côté du tunnel.
Le paquet partait donc dans la mauvaise direction avant même d’avoir une chance d’atteindre Docker.
Le test le plus utile de la matinée a finalement tenu dans une commande :
ip route get 172.18.0.3
Je m’attendais à voir le bridge Docker.
Je voyais la route du VPN.
À ce moment-là, changer de serveur VPN n’avait plus aucun intérêt. Paris, Amsterdam ou Francfort pouvaient être parfaitement rapides : tant que mon ordinateur envoyait 172.18.0.3 au mauvais endroit, aucun serveur distant ne pouvait réparer mon API locale.
Et surtout, je venais enfin de comprendre pourquoi tous mes tests précédents semblaient normaux.
C’est une panne assez étroite pour passer sous presque tous les radars
D’autres développeurs sont tombés dans le même piège.
En octobre 2025, un développeur racontait avoir un VPN apparemment connecté mais ne plus pouvoir atteindre une base de données. Après avoir inspecté les logs, modifié la configuration et même changé de Wi-Fi, il a découvert que Docker avait créé un réseau utilisant la même plage IP que son VPN.
Une discussion sur r/sysadmin montre le problème sous une autre forme : un utilisateur y explique qu’un client Cisco AnyConnect utilisait la même plage que les réseaux Docker par défaut. Le portable continuait à fonctionner, mais Docker ne répondait plus correctement.
C’est ce qui rend ce conflit particulièrement agaçant. Internet n’est pas coupé. Le VPN n’est pas déconnecté. Docker n’affiche pas forcément d’erreur. Seule une tranche précise d’adresses part dans la mauvaise direction.
On peut donc passer une heure à tester le débit, les DNS, les ports ou les conteneurs alors que le problème se trouve quelques lignes plus bas dans ip route.
Une fois cela compris, je n’avais plus vraiment besoin de « réparer le VPN ».
Je devais empêcher Docker et lui de se présenter avec la même adresse.
J’ai arrêté de réparer le tunnel et déplacé la frontière de Docker
La correction durable n’était pas de supprimer manuellement une route après chaque connexion. Elle aurait pu revenir au prochain démarrage du VPN ou à la prochaine création de réseau.
J’avais besoin que Docker et le VPN cessent simplement de se disputer la même plage.
J’ai vérifié les réseaux réellement utilisés avec docker network inspect, puis réservé à Docker un pool privé qui ne chevauchait ni mon LAN ni les plages utilisées par mes VPN. Docker permet précisément de définir ces pools dans daemon.json.
L’idée est plus importante que la valeur exacte : la nouvelle plage doit être réellement libre dans l’environnement où travaille la machine.
Après avoir recréé les réseaux concernés, j’ai relancé la stack.
172.18.0.3 avait disparu de mon architecture.
Le nouvel endpoint répondait. Puis j’ai reconnecté le VPN. Il répondait toujours.
Pour la première fois de la matinée, Docker et le tunnel restaient actifs ensemble sans que je doive choisir lequel j’avais le droit d’utiliser.
C’est là que ma façon de comparer les VPN a changé.
Le VPN que j’ai gardé était celui qui ne me renvoyait pas dans la table de routage
J’avais jusque-là tendance à évaluer un VPN avec les critères habituels : nombre de pays, quantité de serveurs, choix de protocoles, vitesse.
Après cette panne, j’ai ajouté une question beaucoup moins spectaculaire :
que devient mon environnement local quand je clique sur Connecter ?
J’ai donc installé OnlydogVPN sur la même machine de test.
Son approche est plus simple que celle des clients VPN où l’on commence par choisir entre une longue liste de serveurs et de réglages. L’application est organisée autour de scénarios d’usage et cherche à automatiser les décisions courantes plutôt qu’à me demander de reconstruire moi-même la route à chaque connexion.
J’ai connecté le tunnel. Et cette fois, je n’ai même pas commencé par vérifier mon adresse IP publique. J’ai appelé l’API locale. Réponse. J’ai lancé les tests d’intégration. Ils ont continué. J’ai ouvert les services exposés par mes conteneurs. Toujours là.
Ensuite seulement, j’ai vérifié la sortie Internet : le trafic public passait bien par le VPN.
Le résultat qui m’intéressait tenait donc en deux lignes : Internet dans le tunnel ; environnement Docker toujours accessible.
Sur la machine utilisée pour ce test, l’application n’avait pas recréé le conflit de route qui venait de me faire perdre ma matinée.
C’était beaucoup plus convaincant qu’un Speedtest.
Je pouvais laisser la stack tourner, garder le VPN actif et revenir au code.
Le meilleur détail était tout ce que je n’avais plus à administrer
Le service utilise un transport basé sur HTTP/3. C’est utile pour comprendre son comportement sur des réseaux qui changent ou deviennent instables, mais ce n’est pas ce qui avait résolu mon chevauchement d’adresses.
HTTP/3 ne peut pas rendre deux sous-réseaux identiques soudainement différents.
La vraie différence, dans mon cas, était plus concrète : une fois le plan d’adressage Docker corrigé, je pouvais établir le tunnel sans repartir dans une deuxième séance de plomberie réseau.
Je n’avais pas importé un profil.
Je n’avais pas ajouté une exception pour chaque bridge.
Je n’avais pas écrit un script chargé d’effacer puis de recréer des routes après chaque connexion.
J’avais connecté l’application et vérifié les deux choses dont j’avais réellement besoin : le trafic Internet passait par le tunnel et mes conteneurs restaient joignables.
Le service propose moins de régions que les grands fournisseurs et possède un historique public plus court. Pour quelqu’un qui veut une très longue liste de destinations ou un contrôle manuel extrêmement détaillé, cela peut compter.
Pour ma machine de développement, le calcul était différent.
Après avoir passé une matinée à comprendre une route que je n’avais jamais voulu administrer, la simplicité cessait d’être un détail d’interface. Elle devenait précisément la raison de garder l’application.
Le diagnostic que je ferais maintenant prend trente secondes
Si Docker fonctionne lorsque le VPN est coupé et casse dès qu’il est activé, je ne commencerais plus par réinstaller Docker ou changer cinq fois de serveur.
Je regarderais d’abord les plages utilisées par les réseaux Docker. Puis les routes présentes après la connexion du VPN. Enfin :
ip route get <adresse-du-conteneur>
Cette commande répond à la question qui m’avait échappé toute la matinée : où mon ordinateur pense-t-il réellement que cette adresse se trouve ?
Docker peut être healthy. Le VPN peut être connecté. Le Wi-Fi peut fonctionner.
Et pourtant, un paquet destiné à un conteneur local peut partir dans le tunnel simplement parce que deux réseaux ont choisi le même morceau d’espace privé.
C’est pourquoi je ne comparerais plus deux VPN uniquement par leur vitesse ou leur catalogue de serveurs sur une machine de développement.
Le conflit qui m’avait bloqué ne se mesurait pas en mégabits.
Il se lisait dans une route.
Et après l’avoir corrigée, je ne voulais surtout pas d’un VPN qui me transforme à nouveau en administrateur réseau chaque fois que j’appuie sur Connecter.
Je voulais garder le tunnel ouvert et oublier ip route.
Cette fois, c’est exactement ce que j’ai pu faire.
Questions fréquentes
Pourquoi le navigateur et le VPN fonctionnent-ils alors qu’un seul conteneur disparaît ?
Parce qu’un conflit de route peut toucher uniquement la plage privée du conteneur. Le reste d’Internet continue à suivre des routes normales, ce qui rend la panne très étroite.
Quelle commande aide à confirmer que l’adresse du conteneur part dans la mauvaise direction ?
Dans l’article, ip route get suivi de l’adresse du conteneur montre l’interface et la route choisies par Linux pour cette destination.
Quelle est la correction durable d’un chevauchement entre Docker et un réseau VPN ?
Définir pour Docker un pool d’adresses privées qui ne chevauche ni le LAN ni les plages utilisées par les VPN, puis recréer les réseaux concernés afin qu’ils utilisent la nouvelle plage.
Changer de serveur VPN suffit-il à résoudre ce type de panne ?
Non si la cause est l’adresse elle-même. Tant que la table de routage envoie la plage du conteneur vers le tunnel, choisir une autre ville ou un autre serveur ne rétablit pas le bridge Docker.
