Caddy
Honestly the easiest option of the bunch. Caddy handles HTTPS and certificate renewal on its own with zero extra config, and WebSocket proxying just works without any special headers.
Caddyfile
metrics.example.com {
reverse_proxy localhost:8484
} That’s the whole thing. Caddy grabs a certificate from Let’s Encrypt on the first request and renews it automatically from then on.
Set PERCH_BASE_URL
Add PERCH_BASE_URL to your .env so OAuth callbacks point to the right place:
PERCH_BASE_URL=https://metrics.example.com Then restart the hub:
docker compose restart hub Where Caddy is running
If Caddy runs directly on the host, point it at localhost:
metrics.example.com {
reverse_proxy localhost:8484
} If Caddy runs in a container, use the hub’s service name instead of localhost, and make sure Caddy and the hub share a Docker network:
metrics.example.com {
reverse_proxy hub:8484
} Custom domain status pages
Using custom domains on status pages? Add a block for each custom domain pointing at the same backend, and Caddy sorts out the certificate for each one automatically:
metrics.example.com {
reverse_proxy localhost:8484
}
status.yourservice.com {
reverse_proxy localhost:8484
}