If you've tried running n8n in Docker behind Nginx, you've probably hit one of these two mistakes. They're the reason for most "n8n works on localhost but not through my domain" posts you'll find in any n8n or self-hosting community.
Mistake 1: Using expose instead of ports in docker-compose
Wrong:
expose:"5678"
Correct:
ports: "127.0.0.1:8000:5678"
expose
only makes the port visible to other containers on the same Docker network, it doesn't map anything to your host machine. If Nginx is running directly on the host (not in a container on the same Docker network), it has nothing to connect to. Binding to 127.0.0.1:8000:5678 maps container port 5678to host port 8000, but only on localhost, so it's never exposed to the internet directly. Nginx is the only thing that gets a public port.
Mistake 2: Nginx proxying to the wrong port
Wrong:
proxy_pass http://127.0.0.1:5678;
Correct:
proxy_pass http://127.0.0.1:8000;
This one trips people up because 5678 is n8n's own internal port, so it feels like the "right" number to use. But once you remap it in docker-compose (see above), the host only has 8000 open. Pointing Nginx at 5678 means it's trying to reach a port nothing is listening on at the host level, and you'll get connection refused or a silent failure depending on your setup.
The full request flow, for reference:
Internet -> HTTPS:443 -> Nginx -> 127.0.0.1:8000 -> Docker container n8n:5678
Every hop after Nginx stays on localhost. Nothing except Nginx itself is ever reachable from outside the server.
If you want the whole setup end to end:
I wrote up the complete process, from creating a VPS through to a working HTTPS reverse proxy with a real Let's Encrypt certificate, as a PDF: https://danilwave34.gumroad.com/l/bmlkk. It covers DNS, Docker install, the temporary Nginx site Certbot needs, the final proxy config, webhook testing, and a few maintenance commands.
Happy to help debug your specific config in the comments if you're stuck.
Top comments (0)