Skip to content

ADR-0004: Single ingress (Caddy), Cloudflare only at the public edge

Synced read-only from /home/synnet/synvirt-platform/docs-internal/adr/0004-single-ingress-caddy.md. Edit at the source, not here.

ADR-0004: Single ingress (Caddy), Cloudflare only at the public edge

Section titled “ADR-0004: Single ingress (Caddy), Cloudflare only at the public edge”
  • Status: Accepted
  • Date: 2026-06-28

We want one place that routes every subdomain, segmented internal networking, and the ability to move a service to another host by changing one upstream. We also need a real public certificate plus WAF/Turnstile for synvirt.mx.

Caddy is the only ingress in both dev and prod; it is the only service that publishes host ports (80/443). Postgres, Redis, Meilisearch, MinIO and Keycloak stay on the internal network with no published ports (dev binds a few to 127.0.0.1 only, for host-run apps).

  • Dev: Caddy uses an internal CA (tls internal) for *.synvirt.test, honoring the rule that internal services use Caddy’s internal TLS.
  • Prod: synvirt.mx is public. Cloudflare provides DNS / WAF / Turnstile and a Tunnel to Caddy; Caddy (or Cloudflare) terminates real TLS. Cloudflare is decoupleable — Caddy remains the single entry point either way.
  • Moving a service to another host = change one reverse_proxy upstream.
  • Nothing sensitive is exposed; only the public web/API/auth vhosts are reachable.
  • Two Caddyfiles (Caddyfile.dev, Caddyfile.prod) keep dev (host upstreams via host.docker.internal) and prod (container upstreams) cleanly separated.