Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Yes. You can remove Traefik from an n8n Docker Compose deployment and put n8n behind either NGINX or Caddy. Keep n8n listening privately on port 5678, let only the proxy publish ports 80 and 443, and configure n8n with its public HTTPS hostname so webhook URLs, redirects, and the live editor work correctly.
Antihost offers VPS plans with one-click n8n, NVMe storage and a 14-day free trial.
What changes when Traefik is removed?
The official n8n Compose pattern separates the workflow application from the public entry point. n8n listens on port 5678 inside a Docker network, while a reverse proxy accepts Internet traffic, terminates TLS, and forwards requests to the n8n service. Traefik is only one possible proxy; NGINX and Caddy can perform the same role.
As an Amazon Associate I earn from qualifying purchases.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallThe target topology is:
Internet (HTTPS :443)
|
NGINX or Caddy
|
Docker network: n8n:5678
Do not publish n8n’s 5678 port to the public interface when the proxy shares its Docker network. The proxy should be the only service binding host ports 80 and 443. n8n remains reachable by the Compose service name n8n and port 5678.
Requirements before you deploy
- A DNS A or AAAA record for your hostname, such as
n8n.example.com, pointing to the server. - Inbound TCP ports 80 and 443 allowed by the host firewall and any upstream firewall.
- A Docker network shared by n8n and the selected proxy.
- A persistent volume mounted at
/home/node/.n8n. The directory contains n8n’s SQLite database and encryption key in the standard Compose arrangement. - A plan for TLS certificates. Caddy can obtain and renew certificates automatically; NGINX needs certificate files supplied by an ACME client or another approved automation process.
Resolve DNS and confirm public reachability before starting the proxy. Caddy’s certificate issuance, and any HTTP-01 ACME validation used with NGINX, depend on the hostname reaching ports 80 and 443 on this server.
#1 Best Overall
Shared n8n Compose service
Use one n8n service and attach it to a private network. The proxy-specific sections below add either Caddy or NGINX to that network. This example intentionally does not publish port 5678:
services:
n8n:
image: docker.n8n.io/n8nio/n8n
restart: unless-stopped
environment:
- N8N_HOST=n8n.example.com
- N8N_PORT=5678
- N8N_PROTOCOL=https
- N8N_WEBHOOK_URL=https://n8n.example.com/
- N8N_PROXY_HOPS=1
volumes:
- n8n_data:/home/node/.n8n
networks:
- n8n_net
volumes:
n8n_data:
networks:
n8n_net:
N8N_PORT=5678 describes n8n’s internal listener; it is not the public HTTPS port. The public port is 443 at the proxy. N8N_WEBHOOK_URL tells n8n to advertise the externally reachable URL instead of constructing links with an internal address or port.
Option 1: Put n8n behind Caddy
Why choose Caddy?
Caddy is the shorter path when you want automatic HTTPS and do not need extensive hand-written proxy policy. Its Docker Compose deployment guides use a Caddyfile that forwards the Compose hostname to port 5678. Caddy obtains and renews certificates itself, so Certbot does not need to be another service in the stack.
Caddy Compose service
Add Caddy to the same network and publish only its web ports:
services:
n8n:
image: docker.n8n.io/n8nio/n8n
restart: unless-stopped
environment:
- N8N_HOST=n8n.example.com
- N8N_PORT=5678
- N8N_PROTOCOL=https
- N8N_WEBHOOK_URL=https://n8n.example.com/
- N8N_PROXY_HOPS=1
volumes:
- n8n_data:/home/node/.n8n
networks:
- n8n_net
caddy:
image: caddy:2
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
networks:
- n8n_net
depends_on:
- n8n
volumes:
n8n_data:
caddy_data:
caddy_config:
networks:
n8n_net:
The caddy_data volume is important because it stores Caddy’s certificate and account state. Persist it across container recreation; otherwise Caddy may need to obtain certificates again.
Rank #2
Caddyfile
Create Caddyfile beside the Compose file:
n8n.example.com {
reverse_proxy n8n:5678 {
flush_interval -1
}
}
n8n is the Compose service name, not a public DNS name. Docker’s internal DNS resolves it only because both containers join n8n_net. The flush_interval -1 setting disables response buffering for this proxy route, which is useful for n8n’s streaming and interactive behavior.
Start and check Caddy
- Point DNS at the server and open ports 80 and 443.
- Run
docker compose configand check that the n8n service, Caddy service, network, and three volumes render as expected. - Start the stack with
docker compose up -d. - Inspect Caddy’s logs if certificate issuance fails. A DNS record that has not propagated, a blocked port 80, or a hostname that resolves to another address will prevent validation.
- Open
https://n8n.example.com/and verify that the browser receives a valid certificate and the n8n editor loads.
Option 2: Put n8n behind NGINX
When NGINX is the better fit
Choose NGINX when the host already standardizes on it, several applications share one reverse proxy, or you need explicit control over access rules, logging, buffering, and forwarded headers. NGINX gives you that control, but certificate acquisition and renewal are separate operational tasks.
NGINX Compose service
This pattern runs NGINX as a container on the same Docker network. Mount a server configuration and the certificate directory produced by your ACME automation:
services:
n8n:
image: docker.n8n.io/n8nio/n8n
restart: unless-stopped
environment:
- N8N_HOST=n8n.example.com
- N8N_PORT=5678
- N8N_PROTOCOL=https
- N8N_WEBHOOK_URL=https://n8n.example.com/
- N8N_PROXY_HOPS=1
volumes:
- n8n_data:/home/node/.n8n
networks:
- n8n_net
nginx:
image: nginx:stable
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- /etc/letsencrypt:/etc/letsencrypt:ro
networks:
- n8n_net
depends_on:
- n8n
volumes:
n8n_data:
networks:
n8n_net:
If certificates are stored somewhere else, mount that directory read-only and adjust the paths in the server block. The renewal process must replace the files and reload NGINX after a successful renewal.
NGINX configuration with WebSocket forwarding
NGINX uses HTTP/1.0 for upstream connections by default. n8n’s browser interactions can require WebSocket upgrades, so explicitly select HTTP/1.1 and forward the hop-by-hop upgrade headers. Put the map in the top-level http block:
Recommended Free Tools
Rank #3
events {}
http {
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name n8n.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name n8n.example.com;
ssl_certificate /etc/letsencrypt/live/n8n.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/n8n.example.com/privkey.pem;
location / {
proxy_pass http://n8n:5678;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
}
proxy_pass http://n8n:5678 targets the Docker service directly. The Host and X-Forwarded-* headers preserve the public request details that n8n needs to build correct links and recognize HTTPS. The conditional map sends Connection: upgrade only when the client requested an upgrade and sends close for ordinary requests.
Obtain and renew the certificate
Use an ACME client such as Certbot, or another approved certificate automation process, outside the NGINX container. Store the resulting fullchain.pem and privkey.pem at the paths mounted into the container. After renewal, reload NGINX so it reads the new files. A certificate renewal that updates files without a reload does not immediately change the certificate being served.
Configure n8n’s public URL and proxy trust
n8n derives webhook URLs from its protocol, host, and port. The container still listens on 5678, while users reach the service through HTTPS on 443. Set all of these values on the n8n service:
| Variable | Value in this example | Purpose |
|---|---|---|
N8N_HOST |
n8n.example.com |
Public hostname used by the editor and generated links. |
N8N_PORT |
5678 |
n8n’s internal listening port; do not change it to 443 merely because the proxy serves HTTPS. |
N8N_PROTOCOL |
https |
Declares the public scheme. |
N8N_WEBHOOK_URL |
https://n8n.example.com/ |
Explicit public base URL for webhook registration and display. |
N8N_PROXY_HOPS |
1 |
Trusts one reverse-proxy hop when interpreting forwarded headers. |
N8N_WEBHOOK_URL is the current variable. The older WEBHOOK_URL name is deprecated from n8n 2.35.0. The final proxy must set X-Forwarded-For, X-Forwarded-Host, and X-Forwarded-Proto.
If a load balancer or another proxy sits in front of NGINX or Caddy, set N8N_PROXY_HOPS to the number of trusted proxy layers and preserve the forwarding chain at every layer. Do not increase the value simply to silence an error; trusting more hops than actually exist can allow forged client information.
TLS choices and exposure rules
n8n recommends placing a reverse proxy or network load balancer in front of the instance for TLS termination and certificate renewal. Direct TLS inside n8n is possible with N8N_SSL_CERT and N8N_SSL_KEY, but then you must securely mount the private key, renew the certificate, and restart or reload n8n yourself. For most Compose deployments, terminating TLS at Caddy or NGINX keeps certificate operations separate from the workflow container.
- Publish
80:80and443:443on the proxy. - Do not publish
5678:5678to a public host interface. - Keep n8n and the proxy on the same Docker network.
- Persist
/home/node/.n8nand the proxy’s certificate storage. - Allow only the required ports through the host firewall.
NGINX versus Caddy
| Decision factor | Caddy | NGINX |
|---|---|---|
| Configuration size | Usually a short Caddyfile with one reverse_proxy directive. |
Longer server blocks, header rules, TLS paths, and WebSocket handling. |
| Certificates | Automatically obtains and renews certificates when DNS and ports are reachable. | Requires Certbot or another certificate automation process and a reload after renewal. |
| Existing standard | Good choice for a dedicated n8n host with no established proxy. | Natural choice where NGINX already fronts other applications. |
| Multi-application routing | Supports it, but teams may need to learn Caddy’s configuration model. | Widely used for many virtual hosts and detailed routing policies. |
| Header and access control | Concise defaults with additional directives when needed. | Very explicit control over headers, buffering, authentication, and allow/deny rules. |
| Operational overhead | Fewer certificate tasks, but certificate data still must be persisted. | More moving parts around issuance, renewal, file permissions, and reloads. |
Verification checklist after deployment
- Run
docker compose config. Confirm that the proxy, n8n, shared network, persistent n8n volume, and certificate storage are present. - Check that DNS resolves
n8n.example.comto the server’s public IP address, including the correct IPv6 address if an AAAA record exists. - Confirm that the proxy obtains or loads a certificate whose name matches the hostname.
- Run
curl -I https://n8n.example.com/. The response should come from the HTTPS proxy rather than an unencrypted redirect loop or a connection to port 5678. - Load the editor in a browser. Check for mixed-content warnings, repeated redirects, or a page that loads without its scripts.
- Create or inspect a test webhook and confirm that n8n displays an
https://n8n.example.com/URL, notlocalhost, an internal Docker hostname, or port 5678. - Use the editor’s live features and browser developer tools to check the WebSocket request. With NGINX, a successful upgrade normally returns
101 Switching Protocols. - Restart the stack and verify that workflows, credentials, the encryption key, and proxy certificate data remain available.
Common failures and fixes
Webhooks contain localhost or port 5678
This means n8n is constructing URLs from its internal address. Set N8N_HOST, N8N_PROTOCOL=https, and N8N_WEBHOOK_URL to the public values, then recreate the n8n container so the environment is applied. Keep N8N_PORT=5678; changing the internal port is not the fix.
The proxy cannot resolve n8n
The proxy and n8n are not on the same Docker network, or the service name differs from the name in proxy_pass or the Caddyfile. Attach both services to the same network and use the exact Compose service name as the upstream hostname.
Free tools Windows power users keep installed
One-click scans. No signup required.
The editor loads but live updates disconnect
For NGINX, check that proxy_http_version 1.1, Upgrade, and the conditional Connection header are present. A missing upgrade header prevents WebSocket negotiation even though ordinary HTTP pages still work. Also check that an upstream proxy has not removed those headers.
Caddy cannot issue a certificate
Verify DNS, public port 80, public port 443, and firewall rules. Confirm that no other process has captured those ports and that the hostname resolves to this server from outside the local network. Persist Caddy’s /data volume after the first successful issuance.
Best Value
- Docker, Docker Swarm, Docker Compose, Programmer, Developer, Coding, Programming, Software Engineer, Code, DevOps, Deploy, Deployment, Kubernetes, Salt, Puppet, Chef, Terraform, Container, AWS, Azure, Cloud, Geek, Funny, Computer, Software, Tech, IT
- Integration, Scrum, Compile, Compilation, Science, Bug, Debug, Python, Linux, Java, Javascript, Scala, Dotnet, Kotlin
- Lightweight, Classic fit, Double-needle sleeve and bottom hem
NGINX serves an old certificate
Confirm that the renewed files are inside the path mounted into the container, then reload NGINX. File replacement alone does not make a running NGINX worker start serving the new certificate.
Redirect loops or mixed content appear
Ensure the proxy sends X-Forwarded-Proto $scheme and n8n has N8N_PROTOCOL=https. If another proxy is in front, preserve the original HTTPS scheme rather than overwriting it with HTTP.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Data disappears after a container rebuild
Check that /home/node/.n8n is backed by the named or bind-mounted volume shown in Compose. The database and encryption key live there; a disposable container filesystem cannot preserve them.
Operating the stack safely
Back up the n8n data volume, especially the encryption key, before upgrades or migrations. Treat the proxy’s private key and n8n’s encryption key as secrets. Restrict permissions on mounted certificate directories and environment files, and avoid exposing the Docker socket to a proxy container unless a separate, deliberate automation design requires it.
When changing hostnames, update DNS, the proxy’s server name or Caddy site label, the certificate configuration, and all n8n public URL variables together. Test a webhook after the change because existing integrations may retain the old callback URL.
The Bottom Line
Use Caddy when you want the smallest configuration and automatic HTTPS. Use NGINX when you need established multi-application routing and granular policy control. In either case, keep n8n private on port 5678, publish only the proxy on 80/443, persist /home/node/.n8n, and set n8n’s public HTTPS and forwarding variables explicitly.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




