Caddy is an open-source reverse proxy and web server. We use it as the single TLS-terminating entry point for all inbound HTTPS traffic to the home network.

Caddy runs as a Docker container on the n8n Pi (10.20.0.7). All external HTTP/HTTPS traffic enters through it; individual internal services are never directly exposed on ports 80 or 443.

What it does

  • Receives all inbound traffic on ports 80 and 443 (forwarded from the UDM Pro SE)
  • Obtains and renews TLS certificates automatically from Let’s Encrypt via the HTTP-01 challenge — no manual certificate management
  • Routes requests to internal services by hostname (see Caddyfile below)

Routing

Hostname routing is configured in lab/services/caddy/Caddyfile. Each subdomain gets its own block mapping to an internal service:

www.cornillaud.com {
    reverse_proxy n8n:5678
}

Caddy and the services it proxies communicate over a shared Docker network named proxy. Service names (e.g. n8n) resolve to container IPs within that network.

Adding a new subdomain

  1. Add a CNAME DNS record in Cloudflare pointing the new subdomain to www.cornillaud.com (so it inherits the DDNS-maintained A record)
  2. Add a block to Caddyfile for the new hostname
  3. Redeploy: ./provision-service.sh --env prod --host <host> --service caddy

Caddy fetches the Let’s Encrypt certificate for the new hostname automatically on first request.

Deployment

Service definition: lab/services/caddy/

./provision-service.sh --env prod --host <host> --service caddy

The pre-deploy.sh hook creates the shared proxy Docker network if it does not already exist. The caddy_data Docker volume persists certificates across container restarts — do not delete it.