← All articles
NETWORKING Reverse Proxy Comparison: Traefik vs Caddy vs Nginx ... 2026-02-09 · 5 min read · reverse-proxy · traefik · caddy

Reverse Proxy Comparison: Traefik vs Caddy vs Nginx Proxy Manager

Networking 2026-02-09 · 5 min read reverse-proxy traefik caddy nginx networking docker https

Every home lab that runs more than a couple of services needs a reverse proxy. Without one, you're stuck accessing services by IP address and port number — 192.168.1.50:8096 for Jellyfin, 192.168.1.50:9443 for Portainer, 192.168.1.50:8080 for your dashboard. A reverse proxy lets you use proper hostnames like jellyfin.home.lab and handles HTTPS certificates automatically.

The three most popular options in the home lab community are Traefik, Caddy, and Nginx Proxy Manager (NPM). They all get the job done, but they're built for different kinds of users.

Traefik Proxy logo

Quick Comparison

Feature Traefik Caddy Nginx Proxy Manager
Configuration Labels/YAML/TOML Caddyfile/JSON Web GUI
Auto HTTPS Yes (Let's Encrypt, ZeroSSL) Yes (Let's Encrypt, ZeroSSL) Yes (Let's Encrypt)
Docker integration Native (labels) Plugin or manual Manual (GUI)
Dashboard Built-in No Built-in
Learning curve Steep Low Very low
Performance Excellent Excellent Good
Middleware/plugins Extensive Moderate Limited
Memory usage ~50-80MB ~20-40MB ~100-150MB

Nginx Proxy Manager

NPM is the easiest way to get a reverse proxy running. It wraps Nginx in a web GUI where you point and click to create proxy hosts, redirect rules, and SSL certificates. No config files, no command line, no learning curve.

Setup

services:
  nginx-proxy-manager:
    image: jc21/nginx-proxy-manager:latest
    container_name: npm
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "81:81"      # Admin panel
    volumes:
      - ./npm/data:/data
      - ./npm/letsencrypt:/etc/letsencrypt

After deployment, open port 81 and log in with the default credentials ([email protected] / changeme). The GUI walks you through adding proxy hosts — pick a domain, point it at a container's IP and port, toggle SSL on, done.

When to Use NPM

When to Avoid NPM

Caddy

Caddy's philosophy is radical simplicity. Its configuration file (the Caddyfile) is the most readable of any reverse proxy. Automatic HTTPS is truly automatic — Caddy provisions and renews certificates with zero configuration. You just define your domains and backends, and HTTPS happens.

Setup

services:
  caddy:
    image: caddy:latest
    container_name: caddy
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./caddy/Caddyfile:/etc/caddy/Caddyfile
      - ./caddy/data:/data
      - ./caddy/config:/config

Caddyfile:

jellyfin.home.lab {
    reverse_proxy jellyfin:8096
}

portainer.home.lab {
    reverse_proxy portainer:9443 {
        transport http {
            tls_insecure_skip_verify
        }
    }
}

grafana.home.lab {
    reverse_proxy grafana:3000
}

That's it. Three services, three blocks, automatic HTTPS for all of them. Caddy handles certificate provisioning, renewal, OCSP stapling, and HTTP-to-HTTPS redirects with no additional configuration.

When to Use Caddy

When to Avoid Caddy

Caddy for Internal-Only Services

For services that don't face the internet, Caddy can still provide HTTPS using its internal CA:

{
    local_certs
}

proxmox.home.lab {
    reverse_proxy 192.168.1.10:8006 {
        transport http {
            tls_insecure_skip_verify
        }
    }
}

The local_certs directive tells Caddy to issue certificates from its own CA rather than Let's Encrypt. You'll need to trust Caddy's root CA on your devices, but after that, all your internal services get valid HTTPS.

Traefik

Traefik is the most powerful option and the de facto standard for Docker-heavy environments. Its killer feature is Docker label-based configuration: you add labels to your Docker containers, and Traefik automatically creates routes for them. No central config file to update, no GUI to click through. Spin up a container with the right labels and it's proxied immediately.

Setup

services:
  traefik:
    image: traefik:latest
    container_name: traefik
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"   # Dashboard
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./traefik/traefik.yml:/traefik.yml
      - ./traefik/acme.json:/acme.json
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.dashboard.rule=Host(`traefik.home.lab`)"
      - "traefik.http.routers.dashboard.service=api@internal"

traefik.yml:

api:
  dashboard: true

entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
  websecure:
    address: ":443"

providers:
  docker:
    exposedByDefault: false

certificatesResolvers:
  letsencrypt:
    acme:
      email: [email protected]
      storage: /acme.json
      httpChallenge:
        entryPoint: web

Then on any container you want proxied:

services:
  jellyfin:
    image: jellyfin/jellyfin:latest
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.jellyfin.rule=Host(`jellyfin.home.lab`)"
      - "traefik.http.routers.jellyfin.entrypoints=websecure"
      - "traefik.http.routers.jellyfin.tls.certresolver=letsencrypt"
      - "traefik.http.services.jellyfin.loadbalancer.server.port=8096"

When to Use Traefik

When to Avoid Traefik

HTTPS for Home Labs

All three proxies support Let's Encrypt, but home labs have a wrinkle: your services often aren't accessible from the internet, which means the standard HTTP-01 challenge (where Let's Encrypt connects to your server on port 80) doesn't work.

Options:

  1. DNS-01 challenge: All three proxies support DNS challenges. You prove domain ownership by creating a DNS TXT record. Works for internal services. Requires a DNS provider with an API (Cloudflare is the most popular choice).

  2. Cloudflare Tunnel: Put Cloudflare in front and let the tunnel handle HTTPS. Works with any proxy or none at all.

  3. Internal CA: Caddy and Traefik can both act as internal CAs, issuing certificates for .local or .home.lab domains. You'll need to install the root CA on your devices.

  4. Self-signed certificates: Always an option, but you'll get browser warnings. Fine for testing, annoying for daily use.

For most home labs, the DNS-01 challenge with Cloudflare gives the best experience — real certificates, no browser warnings, works for internal services.

Performance

For a typical home lab with 10-30 services, performance differences between these three are irrelevant. They all proxy traffic at line speed and add negligible latency.

Where it matters:

The Verdict

Start with Nginx Proxy Manager if you've never used a reverse proxy. The GUI makes it immediately understandable, and you can always migrate later.

Graduate to Caddy if you want a simpler config file and don't need Docker-native integration. Caddy's Caddyfile is the most pleasant reverse proxy configuration format in existence.

Go with Traefik if you're running a Docker-heavy environment and want services to self-register. The initial learning curve is steeper, but the Docker label approach scales beautifully.

There's no wrong choice here. Pick the one that matches your comfort level and grow from there.