ECONNREFUSED sur localhost : accéder aux services de votre machine depuis n8n sous Docker
Publié le 3 août 2026 · 9 min de lecture
Le scénario est d'une régularité désarmante : Ollama tourne sur votre machine, curl http://localhost:11434 répond parfaitement depuis un terminal, mais le node HTTP Request (ou le node Ollama, ou le node Postgres) de votre n8n installé via Docker renvoie obstinément ECONNREFUSED 127.0.0.1:11434. Rien n'est en panne, aucun pare-feu ne bloque, et pourtant la connexion est refusée. C'est probablement l'erreur la plus fréquente du self-hosting n8n — nous la croisons dans nos guides Postgres comme Ollama — et elle a une seule cause : depuis un conteneur Docker, localhost ne désigne pas votre machine.
Ce guide explique pourquoi, pose le schéma mental qui évite de retomber dans le piège, et déroule les quatre solutions dans l'ordre où il faut les considérer : le nom de service Docker, host.docker.internal, l'IP de la passerelle, et network_mode: host. Avec trois cas concrets à la clé : Ollama, un Postgres local, et le webhook d'une application en développement.
Le symptôme exact
L'erreur prend plusieurs visages selon le node, mais le motif est toujours le même :
ECONNREFUSED 127.0.0.1:11434 ← node HTTP Request ou Ollama
ECONNREFUSED 127.0.0.1:5432 ← credential Postgres
ECONNREFUSED ::1:3000 ← API locale en développement
The service refused the connection
Ce qui rend l'erreur déroutante, c'est que tout fonctionne par ailleurs : le service répond depuis un navigateur ou un curl lancé sur la machine, le port est le bon, aucun mot de passe n'est en cause. ECONNREFUSED ne signifie pas « mauvais identifiants » ni « service planté » : il signifie que rien n'écoute à l'adresse que n8n a appelée. Et l'adresse que n8n a appelée n'est pas celle que vous croyez.
Pourquoi localhost n'est pas votre machine
Un conteneur Docker n'est pas un simple processus : il vit dans son propre espace de noms réseau, avec sa propre interface lo, sa propre table de routage, sa propre adresse IP sur un réseau ponté. C'est précisément ce qui fait la valeur de l'isolation — l'étude de référence de Felter, Ferreira, Rajamony et Rubio chez IBM Research (An updated performance comparison of virtual machines and Linux containers, IEEE ISPASS 2015 — voir sur Google Scholar) montre que les conteneurs offrent des performances proches du natif sur presque tous les plans, le réseau (NAT, pont) étant justement l'une des rares couches où l'isolation introduit un coût et une complexité supplémentaires. Cette complexité, c'est exactement celle que vous rencontrez ici.
Le schéma mental à retenir tient en trois lignes :
- Votre machine (l'hôte) a son
localhostà elle : c'est là qu'écoutent Ollama, votre Postgres installé via apt ou Homebrew, votre application en développement. - Le conteneur n8n a son propre
localhost, distinct : quand n8n appelle127.0.0.1, il frappe à sa propre porte, à l'intérieur du conteneur, où il n'y a rien d'autre que lui. - Les autres conteneurs du même
docker-composesont des voisins sur un réseau partagé, joignables par leur nom de service — jamais parlocalhost.
Autrement dit, ECONNREFUSED 127.0.0.1:11434 se traduit littéralement par : « personne n'écoute sur le port 11434 à l'intérieur du conteneur n8n ». Ce qui est vrai. La question n'est donc pas « pourquoi la connexion est-elle refusée ? » mais « quel nom d'hôte désigne l'endroit où le service tourne vraiment ? ». Il y a quatre réponses possibles.
Solution 1 — le service tourne dans le même docker-compose : le nom du service
C'est le cas le plus simple et la solution la plus propre. Si Ollama, Postgres ou n'importe quel autre service tourne dans un conteneur du même docker-compose que n8n, Docker crée un réseau partagé où chaque service est joignable par son nom :
services:
n8n:
image: docker.n8n.io/n8nio/n8n
ports:
- "5678:5678"
ollama:
image: ollama/ollama
volumes:
- ollama_data:/root/.ollama
postgres:
image: postgres:16
environment:
POSTGRES_PASSWORD: changez-moi
volumes:
ollama_data:
Depuis n8n, l'URL d'Ollama devient http://ollama:11434 et l'hôte du credential Postgres devient postgres (port 5432) — le nom du service, tel qu'il apparaît dans le fichier, fait office de nom DNS. Notez que les conteneurs se parlent sur leurs ports internes, sans avoir besoin de section ports: : la publication de ports ne sert qu'à exposer un service vers l'extérieur du réseau Docker.
Cette solution est à privilégier chaque fois que c'est possible : elle est portable (le même fichier fonctionne sur Mac, Windows, Linux, un VPS), survit aux redémarrages et aux changements d'IP, et garde tout le trafic à l'intérieur du réseau Docker. Si vous partez de zéro, notre guide d'installation de n8n avec Docker pose ce socle docker-compose proprement — et il reste stable au fil des mises à jour de n8n.
Solution 2 — le service tourne sur la machine hôte : host.docker.internal
Deuxième cas : le service ne tourne pas dans Docker, mais directement sur la machine — un Ollama installé via le script officiel, un Postgres système, une application que vous développez. Docker fournit pour cela un nom d'hôte spécial, host.docker.internal, qui pointe vers la machine hôte depuis l'intérieur d'un conteneur.
Sur Docker Desktop (Mac et Windows), ce nom fonctionne nativement, sans aucune configuration. Remplacez simplement localhost par host.docker.internal dans l'URL ou le credential :
http://localhost:11434 → http://host.docker.internal:11434
Sur Linux (le cas typique d'un VPS), ce nom n'existe pas par défaut. Il faut le déclarer explicitement dans le docker-compose, via extra_hosts et la valeur magique host-gateway :
services:
n8n:
image: docker.n8n.io/n8nio/n8n
ports:
- "5678:5678"
extra_hosts:
- "host.docker.internal:host-gateway"
Puis recréez le conteneur (docker compose up -d).
Le piège dans le piège : le service doit écouter au-delà de 127.0.0.1
C'est ici que la moitié des dépannages échouent. Beaucoup de services n'écoutent par défaut que sur 127.0.0.1, c'est-à-dire uniquement les connexions venant de la machine elle-même. Or une connexion arrivant du conteneur n8n via host.docker.internal entre par l'interface du pont Docker, pas par la boucle locale : le service la refuse, et vous obtenez… ECONNREFUSED, avec pourtant le bon nom d'hôte.
Ollama est l'exemple canonique : par défaut il n'écoute que sur 127.0.0.1:11434. Il faut lui dire d'écouter sur toutes les interfaces :
# Linux (service systemd)
sudo systemctl edit ollama
# ajouter :
# [Service]
# Environment="OLLAMA_HOST=0.0.0.0"
sudo systemctl restart ollama
Même logique pour un Postgres hôte (listen_addresses dans postgresql.conf, plus une règle pg_hba.conf pour le sous-réseau Docker) ou un serveur de développement (npm run dev -- --host 0.0.0.0, par exemple). Le duo à vérifier est donc toujours le même : le bon nom d'hôte côté n8n, et une écoute qui dépasse 127.0.0.1 côté service. Si vous ouvrez un service sur 0.0.0.0 sur un VPS exposé à Internet, pensez au pare-feu : n'ouvrez le port qu'au sous-réseau Docker, pas au monde entier.
Solution 3 — l'IP de la passerelle Docker : possible, mais fragile
Sur Linux, la machine hôte est aussi joignable depuis un conteneur via l'IP de la passerelle du pont Docker — 172.17.0.1 par défaut sur le réseau bridge, une autre adresse (souvent en 172.18.x.x ou au-delà) sur les réseaux créés par docker compose. Vous pouvez la trouver avec docker network inspect et l'utiliser telle quelle comme hôte.
Ça fonctionne, mais nous ne le recommandons pas : l'adresse dépend du réseau sur lequel le conteneur est attaché, peut changer si vous recréez les réseaux, et rend le docker-compose non portable d'une machine à l'autre. extra_hosts: - "host.docker.internal:host-gateway" fait exactement la même chose en laissant Docker résoudre la bonne adresse à chaque démarrage. Réservez l'IP brute au diagnostic ponctuel.
Solution 4 — network_mode: host : le dernier recours
Sur Linux uniquement, il est possible de supprimer purement et simplement l'isolation réseau du conteneur :
services:
n8n:
image: docker.n8n.io/n8nio/n8n
network_mode: host
Le conteneur partage alors l'espace réseau de l'hôte : localhost redésigne la machine, tout fonctionne « comme avant Docker ». Mais le prix est réel : plus d'isolation réseau, plus de section ports: (elle est ignorée, n8n écoute directement sur le port 5678 de l'hôte), plus de nom de service pour joindre les autres conteneurs, et une incompatibilité avec Docker Desktop sur Mac et Windows. C'est une solution de dernier recours, pour des cas très particuliers — pas une réponse par défaut à un ECONNREFUSED que la solution 2 règle proprement.
Trois cas concrets
Ollama sur l'hôte, n8n dans Docker. Le cas star depuis l'essor des LLM locaux, détaillé dans notre guide n8n + Ollama sans clé API. Recette complète : extra_hosts: - "host.docker.internal:host-gateway" côté n8n, OLLAMA_HOST=0.0.0.0 côté Ollama, et l'URL de base http://host.docker.internal:11434 dans le credential Ollama de n8n. Si vous pouvez au contraire faire tourner Ollama en conteneur dans le même compose, c'est encore plus simple : http://ollama:11434, sans rien d'autre.
Postgres local. Même arbitrage. Postgres en conteneur voisin : hôte postgres, port 5432 dans le credential — le cas nominal de notre guide du node Postgres. Postgres installé sur la machine : hôte host.docker.internal, après avoir vérifié listen_addresses et pg_hba.conf.
Tester le webhook d'une application en développement. Vous développez une API sur http://localhost:3000 et voulez que n8n l'appelle : http://host.docker.internal:3000, avec un serveur de dev qui écoute sur 0.0.0.0. C'est le complément exact de notre guide sur tester les webhooks n8n en local, qui couvre le trajet inverse — faire entrer des requêtes externes vers votre n8n.
Et dans l'autre sens ?
La confusion joue parfois à front renversé : accéder à n8n depuis la machine ou depuis Internet. Depuis l'hôte, c'est le rôle de la publication de ports — la ligne ports: - "5678:5678" du compose fait que http://localhost:5678 fonctionne dans votre navigateur (là, localhost est légitime : vous êtes sur l'hôte). Pour exposer l'interface et les webhooks à Internet avec un vrai nom de domaine et HTTPS, la publication de ports ne suffit plus : c'est l'objet de notre guide HTTPS et nom de domaine avec Traefik ou Caddy.
Pièges fréquents
- Corriger l'URL en
host.docker.internalmais laisser le service écouter sur127.0.0.1seul : la connexion reste refusée avec le bon nom d'hôte. Pour Ollama,OLLAMA_HOST=0.0.0.0fait partie de la solution au même titre que le nom d'hôte. - Utiliser
extra_hostssur Mac ou Windows en pensant que c'est requis : Docker Desktop fournithost.docker.internalnativement ; la lignehost-gatewayn'est indispensable que sous Linux (et elle ne casse rien ailleurs). - Mettre
host.docker.internalpour un service qui tourne dans le même compose : entre conteneurs voisins, c'est le nom de service qui s'impose (http://ollama:11434), plus simple et plus robuste. - Coder en dur
172.17.0.1: l'adresse varie selon le réseau Docker et la machine ; préférezhost-gateway, qui la résout automatiquement. - Ajouter une section
ports:pour permettre à n8n de joindre un conteneur voisin : la publication de ports expose vers l'extérieur ; entre conteneurs d'un même réseau, elle est inutile. - Passer à
network_mode: hostau premier ECONNREFUSED : on perd l'isolation et la maîtrise des ports publiés pour un problème queextra_hostsrègle en une ligne. - Oublier de recréer le conteneur après modification du compose :
extra_hostsne prend effet qu'après undocker compose up -d.
En résumé
ECONNREFUSED 127.0.0.1 depuis n8n sous Docker n'est presque jamais une panne : c'est localhost qui ne désigne pas ce que vous croyez. Le réflexe à ancrer tient en deux questions. Où tourne le service ? S'il est dans le même docker-compose, appelez-le par son nom de service (http://ollama:11434, hôte postgres). S'il tourne sur la machine hôte, appelez host.docker.internal — avec extra_hosts: - "host.docker.internal:host-gateway" sous Linux — et vérifiez qu'il écoute au-delà de 127.0.0.1. L'IP de passerelle et network_mode: host restent des outils de diagnostic ou de dernier recours, pas des solutions par défaut. Cette plomberie réseau est précisément le prérequis d'un assistant IA 100 % local : un RAG avec Ollama, c'est n8n qui doit joindre à la fois le LLM et la base vectorielle sans qu'aucun octet ne sorte de votre machine. Le Pack Assistant RAG (119 €) livre ce pipeline complet — ingestion, vectorisation, chat — prêt à brancher sur l'architecture Docker que vous venez de mettre d'équerre.
FAQ
Questions fréquentes
Pourquoi n8n sous Docker renvoie ECONNREFUSED 127.0.0.1:11434 alors qu'Ollama tourne bien sur ma machine ?
Parce qu'un conteneur Docker a son propre espace réseau : quand n8n appelle localhost ou 127.0.0.1, il se parle à lui-même, à l'intérieur du conteneur, pas à votre machine. Ollama tourne bien, mais de l'autre côté d'une frontière réseau. Remplacez localhost par host.docker.internal (en ajoutant extra_hosts avec host-gateway dans le docker-compose sous Linux) et vérifiez qu'Ollama écoute sur toutes les interfaces avec OLLAMA_HOST=0.0.0.0 — sinon la connexion reste refusée même avec le bon nom d'hôte.
Faut-il utiliser host.docker.internal ou le nom du service Docker pour connecter n8n à Postgres ?
Cela dépend d'où tourne Postgres. S'il est dans le même docker-compose que n8n, utilisez le nom du service (par exemple postgres comme hôte, port 5432) : les deux conteneurs partagent un réseau Docker où ce nom se résout directement, c'est la solution propre et portable. host.docker.internal ne sert que dans l'autre cas — un Postgres installé directement sur la machine hôte, hors Docker.
host.docker.internal ne fonctionne pas sur mon serveur Linux, que faire ?
Contrairement à Docker Desktop sur Mac et Windows, Docker sous Linux ne crée pas ce nom d'hôte automatiquement. Ajoutez au service n8n de votre docker-compose la section extra_hosts avec la ligne host.docker.internal:host-gateway, puis recréez le conteneur. Si la connexion est toujours refusée, le service visé n'écoute probablement que sur 127.0.0.1 : configurez-le pour écouter sur 0.0.0.0 ou au moins sur l'interface du pont Docker.
Bundle FlowKit Complet
269 €