Skip to content

Ingress & Reverse Proxy

Broch serves plain HTTP on port 8080 and doesn’t terminate TLS, so every deployment needs a reverse proxy (ingress) in front of it. The wildcard certificate lives on the proxy, not on Broch.

Which proxy is up to you. The Docker Compose stacks and the DigitalOcean Droplet bundle Caddy for convenience, set up to serve the wildcard certificate, issued automatically or your own. Any proxy that meets the requirements below works instead. To use your own with Docker Compose, remove the caddy service and publish Broch’s port 8080 only where your proxy can reach it, such as 127.0.0.1:8080:8080.

Platform Ingress
Docker Compose The bundled Caddy, or your own reverse proxy
DigitalOcean (Terraform) Caddy on the Droplet, as with Docker Compose
Azure Container Apps (beta) The built-in Container Apps ingress, or an Application Gateway or load balancer in front of it
AWS ECS Fargate (beta) An Application Load Balancer

Regardless of which ingress you use, it must:

  • Terminate TLS for broch.{your-domain} and *.broch.{your-domain}
  • Forward all traffic to Broch on port 8080
  • Pass X-Forwarded-For, X-Forwarded-Proto, and Host headers
  • Support WebSocket upgrades (Upgrade: websocket, Connection: upgrade) — tunnel connections use WebSockets
  • Briefly retry the connection to Broch when it is momentarily unavailable — a restart or image upgrade — instead of returning an immediate 502

If you bring your own reverse proxy, verify these headers are forwarded correctly. Missing WebSocket support will prevent tunnels from connecting.

Broch is a single process. Restart it — docker compose up -d, an image upgrade — and it is unreachable for a second or two. An ingress that forwards once and gives up turns that into a user-visible 502. An ingress that briefly retries the connection holds the request until Broch is back.

The bundled Caddy templates do this:

reverse_proxy broch:8080 {
header_up Host {host}
lb_try_duration 30s
lb_try_interval 250ms
}

Bringing your own proxy? Configure an equivalent connect-retry — nginx proxy_next_upstream error timeout with proxy_next_upstream_tries, or a load balancer’s health checks plus connection draining. This covers Broch being briefly unreachable; it does not change how a 5xx that Broch itself returns is handled.

On a managed platform, such as the Azure Container Apps ingress or an AWS Application Load Balancer, the load balancer’s health checks and connection draining handle the restart; you configure nothing. Broch runs as a single instance on every platform, so nothing routes around a restart: the Caddy setup waits one out with lb_try_duration instead.

Broch reads the real client IP from X-Forwarded-For, but only from proxies it trusts. A proxy on a different host or container from Broch needs its range trusted. Configuration → Reverse Proxy shows what each platform already sets and when to change it.

Next: Identity Providers, step 5 of the self-managed checklist.