Skip to content

TLS Certificates

Broch requires a wildcard TLS certificate for your chosen hostname (e.g. *.tunnels.company.com). Every tunnel URL is a subdomain, so a single-domain certificate is not sufficient.

Broch itself doesn’t terminate TLS — that’s the job of the reverse proxy or load balancer in front of it. Each deployment platform handles certs differently:

Two compose variants cover the two paths:

Option A — Caddy with automatic ACME (recommended): with-postgres ships a Caddyfile that obtains and renews the wildcard cert automatically via ACME DNS-01. You provide a DNS provider API token at startup; no manual certificate management. Requires DNS on a Caddy-supported provider. Cloudflare is the default; the Dockerfile + Caddyfile documents swapping to Route 53, Google Cloud DNS, Gandi, etc.

For Cloudflare: create an API token scoped to your zone with Zone:Read + DNS:Edit (the dashboard’s “Edit zone DNS” template, at https://dash.cloudflare.com/profile/api-tokens) and pass it as CLOUDFLARE_API_TOKEN. Caddy proves zone control via DNS-01 and Let’s Encrypt issues the wildcard — you never create certificate records by hand.

Turn the Cloudflare proxy (orange cloud) OFF for these records. The proxy re-encrypts with its own certificate (conflicting with Caddy’s TLS), hides real client IPs, and the DNS-01 challenge must reach Cloudflare’s DNS API rather than the proxy edge.

Option B — Bring your own cert: with-postgres-byo-cert ships a Caddyfile with auto_https off and a static tls directive pointing at cert files you provide. Use this when your DNS isn’t on a Caddy-supported provider, you have central PKI / a commercial CA, you use certbot externally with your own renewal automation, or you’re in a restricted-egress network where Caddy can’t reach Let’s Encrypt during issuance.

single-host doesn’t terminate TLS at all — it exposes broch directly on port 8080 for private-network use.

The default Container Apps managed cert handles the apex hostname fine but doesn’t issue wildcards. For tunnel subdomains (*.tunnels.company.com), you have three options:

  1. Front Door / Application Gateway with a managed wildcard in front of Container Apps. Adds a Front Door resource but is the cleanest production answer.
  2. Provision a wildcard cert separately (Let’s Encrypt via certbot+DNS, or commercial CA) and upload it via az containerapp env certificate upload + az containerapp hostname bind.
  3. Skip wildcards if your deployment doesn’t use tunnel subdomains.

See the Azure installation guide and the module README for the binding flow.

AWS Certificate Manager (ACM) handles the wildcard cert via DNS validation. The Terraform module creates an ACM cert covering both the apex and *.<wildcard>, then DNS-validates it against your Route 53 zone — all automatic on terraform apply. ACM handles automatic renewal in perpetuity. No manual cert management.

See the AWS installation guide.

Same shape as Docker Compose Option A — the Droplet runs Caddy with ACME DNS-01. Your DNS provider’s API token is passed as a Terraform variable at apply time. Caddy issues and renews both the apex and wildcard certs.

See the DigitalOcean installation guide.