Le VPN fonctionnait. C’était justement ce qui rendait la panne déroutante. J’avais placé qBittorrent derrière Gluetun, relancé les conteneurs et vérifié l’adresse IP de sortie. Elle avait changé. Le trafic passait bien par le tunnel. Parfait. Puis j’ai ouvert l’interface web que j’utilisais cinq minutes plus tôt :
192.168.1.20:8080 Rien. J’ai actualisé. Toujours rien.
Le conteneur qBittorrent tournait. Gluetun était healthy. Le VPN était connecté. Les logs ne montraient pas l’erreur évidente que j’espérais trouver.
J’avais donc obtenu exactement ce que je voulais — protéger le conteneur — et perdu exactement ce dont j’avais besoin pour l’utiliser.
Ma première réaction a été d’accuser le pare-feu de Gluetun. En réalité, j’avais surtout laissé la porte d’entrée à l’ancienne adresse.
Résumé de l’article et adéquation du produit
Où publier le port local de qBittorrent lorsqu’il partage la pile réseau de Gluetun ?
Avec network_mode: "service:gluetun", qBittorrent utilise la pile réseau de Gluetun. Le port WebUI destiné à l’hôte ou au LAN doit donc être publié sur le service Gluetun, pas sur le service qBittorrent qui n’a plus sa propre pile réseau.
Pourquoi cela correspond à cet article
- Idéal pour : une stack Docker où qBittorrent sort bien par le VPN Gluetun mais où l’interface locale sur le port 8080 disparaît après l’activation de network_mode: "service:gluetun".
- Détail de l’article : le correctif ne consiste pas à supprimer le VPN ni à ouvrir un port entrant côté fournisseur : il consiste à déplacer la publication du port vers la pile réseau qui reçoit désormais le trafic.
- Adéquation OnlydogVPN : le corps de l’article ne nomme pas OnlydogVPN comme composant de cette stack Docker ; il décrit seulement une petite application séparée pour les appareils ordinaires. Le problème Gluetun/qBittorrent doit donc être résolu dans Docker, pas attribué à OnlydogVPN.
- Limite importante : les réglages FIREWALL_INPUT_PORTS, FIREWALL_OUTBOUND_SUBNETS et le port forwarding côté fournisseur répondent à d’autres trajets ; ils ne compensent pas une publication Docker placée sur le mauvais service.
Sources déjà utilisées dans l’article : Gluetun — partage de pile réseau; Docker Compose; Gluetun — port mapping; Docker — publication des ports.
J’avais déplacé le réseau sans déplacer la porte
Avant Gluetun, mon fichier Compose ressemblait à quelque chose de très banal :
qbittorrent:
image: lscr.io/linuxserver/qbittorrent
ports:
- "8080:8080"
Le raisonnement est naturel. qBittorrent écoute sur 8080. Donc je publie 8080 dans le service qBittorrent. Puis j’ai ajouté :
network_mode: "service:gluetun"
Le trafic Internet a commencé à sortir par le VPN. Et l’interface locale a disparu. Tout se joue presque dans cette seule ligne.
Avec network_mode: "service:gluetun", le conteneur qBittorrent utilise la pile réseau du service Gluetun. C’est le fonctionnement documenté à la fois par Gluetun et Docker.
qBittorrent continue donc à exécuter l’application. Mais, du point de vue réseau, il habite désormais chez Gluetun. Et moi, j’avais laissé la sonnette sur son ancienne porte.

Le port 8080 devait déménager lui aussi
La documentation de Gluetun donne la règle qui m’avait manqué : lorsqu’une application partage la pile réseau de Gluetun, les ports que l’on veut rendre accessibles depuis l’hôte doivent être publiés sur Gluetun.
La correction ressemblait donc à ceci :
services:
gluetun:
image: qmcgaw/gluetun:v3
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun:/dev/net/tun
ports:
- "192.168.1.20:8080:8080"
qbittorrent: image: lscr.io/linuxserver/qbittorrent network_mode: "service:gluetun" `` Plus de ports: sous qBittorrent. Le port 8080 est publié par Gluetun, puisque c’est désormais sa pile réseau qui reçoit le trafic. J’ai relancé la stack. Puis : 192.168.1.20:8080`
L’interface est revenue.
Je pouvais à nouveau administrer qBittorrent depuis mon réseau local, alors que ses connexions Internet continuaient à sortir par le tunnel.
C’était exactement le résultat que je cherchais. Pas « VPN ou accès local ». Les deux.
Le port n’« appartient » pas à qBittorrent comme je l’imaginais
C’est probablement l’idée qui m’aurait fait gagner le plus de temps. Dans ma tête, le port 8080 appartenait à qBittorrent parce que c’était son interface web. Docker raisonne plutôt en chemins réseau.
Avec Gluetun, la bonne question n’est donc plus :
Quelle application affiche cette interface ?
Mais :
Dans quelle pile réseau cette interface écoute-t-elle maintenant ?
Avec network_mode: "service:gluetun", la réponse est Gluetun. C’est là que la porte doit se trouver.
Une fois cette idée comprise, la configuration a cessé de ressembler à une collection de règles Docker arbitraires.
J’avais déplacé l’appartement. J’avais simplement oublié de déplacer l’interphone.
Je n’étais manifestement pas le seul à chercher du mauvais côté
Une discussion publique de juin 2026 montre à quel point ce piège reste facile à rencontrer.
Un utilisateur essayait de faire fonctionner qBittorrent derrière Gluetun avec network_mode: "service:gluetun". Les éléments semblaient fonctionner séparément, mais leur assemblage posait problème. Parmi les corrections appliquées figurait précisément le déplacement du port 8080 de l’interface qBittorrent sous le service Gluetun.
Sa configuration comportait d’autres particularités, mais son problème m’intéressait pour une raison très simple.
On voit qBittorrent. On veut accéder à qBittorrent. Alors on cherche naturellement le port dans qBittorrent. Le partage de pile réseau casse cette intuition.
Et une fois cette intuition corrigée, je pouvais arrêter de modifier des réglages qui n’étaient pas responsables de ma panne.
J’ai failli confondre deux « port forwarding »
Le mot port m’a quand même envoyé vers une dernière fausse piste. Gluetun parle également de port forwarding côté VPN.
Je me suis donc demandé si mon interface locale était inaccessible parce que mon fournisseur VPN ne m’avait pas attribué de port entrant.
Ce n’est pas le même trajet. Le port publié dans Compose sert ici à faire : ordinateur local → serveur Docker → Gluetun → interface de l’application.
Le port forwarding proposé par certains fournisseurs VPN concerne, lui, des connexions arrivant depuis le côté VPN.
Pour récupérer ma WebUI sur le LAN, je n’avais pas besoin d’exposer 8080 à Internet. J’avais besoin que Docker sache où envoyer le trafic destiné à 192.168.1.20:8080. Cette distinction m’a évité de réparer le mauvais côté du tunnel.
Je n’ai pas ouvert 8080 plus largement que nécessaire
J’aurais aussi pu écrire simplement :
ports:
- "8080:8080"
Pour une interface d’administration, je préfère savoir où j’ouvre la porte. Si elle ne doit être accessible que depuis la machine Docker :
ports:
- "127.0.0.1:8080:8080"
Si je veux l’atteindre depuis mon LAN, je peux la lier à l’adresse locale du serveur :
ports:
- "192.168.1.20:8080:8080"
Cette petite précision m’a semblé beaucoup plus utile que d’ajouter des règles de pare-feu au hasard jusqu’à obtenir une réponse.
D’autant que, pour certaines communications entre conteneurs, je n’ai même pas besoin de publier un port sur l’hôte. Des conteneurs partageant la pile de Gluetun peuvent communiquer via localhost, tandis qu’un conteneur correctement placé sur le même réseau Docker peut joindre un service derrière Gluetun par son nom et son port.
Autrement dit : je n’ouvre sur mon LAN que ce que j’ai réellement besoin d’y atteindre.
Le pare-feu de Gluetun n’était pas mon premier problème
J’avais pourtant déjà commencé à regarder FIREWALL_INPUT_PORTS et FIREWALL_OUTBOUND_SUBNETS.
Ces options sont utiles lorsque le problème vient réellement des règles d’accès. Gluetun permet notamment d’autoriser certains sous-réseaux nécessaires aux conteneurs qui utilisent sa pile réseau.
Mais aucune règle de pare-feu ne pouvait rendre élégante une publication de port placée au mauvais endroit.
Je modifiais les règles d’entrée d’un immeuble alors que je continuais à sonner à l’ancienne adresse. Depuis, mon diagnostic est beaucoup plus court. L’application écoute-t-elle réellement sur son port ? Partage-t-elle la pile réseau de Gluetun ? Si oui, le port destiné à l’hôte est-il publié sur Gluetun ?
Dans mon cas, la troisième question suffisait.
C’est aussi là que j’ai compris ce que je ne voulais pas mettre derrière Docker
Une fois qBittorrent réparé, j’ai eu le réflexe classique : puisque ce montage fonctionne, pourquoi ne pas l’étendre à tout ?
Ordinateur portable. Téléphone. Navigation quotidienne. Puis j’ai regardé le fichier Compose que je venais de corriger.
Pour qBittorrent, cette plomberie avait du sens. Je voulais qu’un service précis sorte par un tunnel précis, tout en contrôlant exactement ce qui restait accessible sur mon réseau local.
Pour mon ordinateur et mon téléphone, je voulais presque l’inverse. Je ne voulais pas penser en namespaces, en ports publiés ou en conteneurs partageant une pile réseau. Je voulais choisir ce que j’étais en train de faire et connecter. C’est là que la petite application que j’utilise à côté a trouvé une place beaucoup plus naturelle.
Sur mes appareils ordinaires, je garde son approche centrée sur l’usage : je lance le service, choisis le mode adapté et laisse l’application gérer le tunnel. Je réserve Gluetun aux conteneurs pour lesquels cette architecture apporte réellement quelque chose.
Ce n’est pas une tentative de remplacer Gluetun. C’est précisément ce qui rend la combinaison intéressante.
Gluetun me donne le contrôle fin dont j’ai besoin sur mon serveur. Le petit service m’évite de transporter cette complexité jusque sur les appareils où elle ne m’apporte rien.
Il dispose de moins de recul public et de moins de possibilités d’infrastructure avancée qu’un montage Gluetun soigneusement configuré. Mais sur mon téléphone ou mon portable, je n’ai justement aucune envie de reconstruire ce montage.
Mon conteneur n’avait jamais perdu son interface
C’est finalement ce qui rendait la panne si trompeuse. qBittorrent tournait. Son interface écoutait. Le VPN fonctionnait. Gluetun faisait son travail.
J’avais simplement changé l’endroit où vivait le réseau sans changer l’endroit où j’avais placé sa porte.
Après avoir déplacé 8080:8080 sous Gluetun, l’interface locale est revenue et le conteneur a continué à sortir par le tunnel.
Je pensais devoir choisir entre protéger le conteneur et conserver son accès local. Je n’avais pas à choisir.
Avecnetwork_mode: "service:gluetun", si je veux atteindre l’application depuis l’hôte ou le LAN, je publie son port là où son réseau vit désormais : sur Gluetun.
Quelques liens que j’avais ouverts à l’époque
- Gluetun Wiki — Connect a container to Gluetun, utilisation de network_mode: "service:gluetun" pour partager la pile réseau de Gluetun
- Docker Docs — Define services in Docker Compose, fonctionnement de network_mode: service:{name}
- Gluetun Wiki — Port mapping, publication sur Gluetun des ports des applications qui partagent sa pile réseau
- Docker Docs — Publishing and exposing ports et Port publishing and mapping, fonctionnement de HOST_PORT:CONTAINER_PORT et portée des adresses de publication — lien 1 · lien 2
- Reddit r/gluetun — discussion publique de juin 2026 sur qBittorrent derrière Gluetun, network_mode: "service:gluetun" et le déplacement du port 8080 sous Gluetun
- Gluetun Wiki — Inter-containers networking, communication entre conteneurs partageant la pile réseau de Gluetun ou appartenant au même réseau Docker
- Gluetun Wiki — documentation du pare-feu et de FIREWALL_OUTBOUND_SUBNETS pour l’accès aux sous-réseaux nécessaires
Questions fréquentes
Pourquoi qBittorrent continue-t-il de télécharger derrière Gluetun alors que sa WebUI locale ne répond plus ?
Parce que le trafic Internet du conteneur peut déjà passer par la pile réseau de Gluetun alors que le port local est encore publié au mauvais endroit. L’application fonctionne, mais l’hôte n’a plus de porte d’entrée vers la nouvelle pile réseau.
Où faut-il placer 8080:8080 avec network_mode: "service:gluetun" ?
Sur le service Gluetun. Le conteneur qBittorrent continue d’exécuter l’application, mais son réseau vit désormais dans la pile de Gluetun, qui doit donc recevoir la publication destinée à l’hôte ou au LAN.
Le port forwarding du fournisseur VPN est-il nécessaire pour récupérer la WebUI sur le LAN ?
Non. Ce sont deux trajets différents. La publication Docker sert à joindre l’interface depuis le réseau local ; le port forwarding du fournisseur concerne des connexions arrivant depuis le côté VPN.
Faut-il modifier d’abord le pare-feu de Gluetun lorsque l’interface locale disparaît ?
Pas forcément. L’article recommande de vérifier d’abord où l’application écoute, si elle partage la pile de Gluetun et si le port destiné à l’hôte est publié sur Gluetun. Dans le cas raconté, cette troisième vérification suffisait.
