Halloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix NowHalloween DealsAmazon USOctober picks are moving - compare before checkoutAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk10 min

n8n Docker Compose Without Traefik: Use NGINX or Caddy as the Reverse Proxy

A complete guide to replacing Traefik in an n8n Docker Compose deployment with NGINX or Caddy, including private port 5678, TLS, WebSockets, and webhook configuration.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The 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.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Start and check Caddy

  1. Point DNS at the server and open ports 80 and 443.
  2. Run docker compose config and check that the n8n service, Caddy service, network, and three volumes render as expected.
  3. Start the stack with docker compose up -d.
  4. 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.
  5. 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:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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:80 and 443:443 on the proxy.
  • Do not publish 5678:5678 to a public host interface.
  • Keep n8n and the proxy on the same Docker network.
  • Persist /home/node/.n8n and 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.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Verification checklist after deployment

  1. Run docker compose config. Confirm that the proxy, n8n, shared network, persistent n8n volume, and certificate storage are present.
  2. Check that DNS resolves n8n.example.com to the server’s public IP address, including the correct IPv6 address if an AAAA record exists.
  3. Confirm that the proxy obtains or loads a certificate whose name matches the hostname.
  4. 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.
  5. Load the editor in a browser. Check for mixed-content warnings, repeated redirects, or a page that loads without its scripts.
  6. Create or inspect a test webhook and confirm that n8n displays an https://n8n.example.com/ URL, not localhost, an internal Docker hostname, or port 5678.
  7. 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.
  8. 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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 Container Linux Devops Programming Coding T-Shirt
  • 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.