Skip to content

DNS and Cluster Routing

Navigator reconciles public DNS and certificates from Quartermaster inventory. This page owns both root service DNS and media-cluster routing; avoid keeping a separate GeoDNS table elsewhere.


FrameWorks uses two routing layers:

  • DNS layer: Sends clients to the right public service or media cluster.
  • Application layer: Foghorn applies health, capacity, stream availability, and cluster federation rules before returning or redirecting to a node.

Cloudflare remains authoritative for root/API/web/admin/support names. Media and edge traffic is cluster-scoped and may be delegated to Bunny DNS so edge growth does not consume root-domain load-balancing capacity.

Navigator (api_dns) automatically manages DNS based on node inventory from Quartermaster:

  1. Quartermaster triggers a DNS sync (for example, when nodes are created/registered)
  2. Navigator fetches nodes for that service type and filters to those with external IPs
  3. Updates the authoritative provider:
    • Root/API/web/admin names → Cloudflare A records or load balancers
    • Multiple nodes on root/global hostnames → Cloudflare load balancer with one proximity-steered pool per Quartermaster cluster
    • Media cluster names → Bunny A-record sets with geolocation Smart Routing when coordinates are available
  4. Applies proxying rules (default: chartroom, foredeck, and logbook)
  5. Handles ACME certificate issuance via DNS-01 challenges

If no nodes are returned for a service type, Navigator skips changes to avoid removing working DNS during a transient outage.

Use the CLI to verify public DNS matches your inventory:

Terminal window
frameworks dns doctor --domain yourdomain.com

This checks:

  • Each subdomain resolves to expected IPs from inventory
  • Reports mismatches between public DNS and Quartermaster

Pass --domain; default domains are for development and platform-owned checks.


SubdomainPurposeService
example.comMarketing siteForedeck (Website)
chartroom.example.comWeb consoleChartroom
bridge.example.comGraphQL APIBridge
logbook.example.comDocs siteLogbook
steward.example.comForms APISteward
listmonk.example.comNewsletter/adminListmonk
chatwoot.example.comSupport inboxChatwoot

Cloudflare remains authoritative for root/API/web/admin/support names. Navigator can reconcile those records through Cloudflare, but media and edge traffic is cluster-scoped and delegated to Bunny DNS.

Internal Services (Private Network / Mesh)

Section titled “Internal Services (Private Network / Mesh)”

These services communicate over the private network or WireGuard mesh (Privateer) and do not need public DNS. Edge nodes do not join the mesh.

  • Commodore, Purser, Periscope, Quartermaster, Signalman
  • PostgreSQL, ClickHouse, Kafka

Configure via environment variables with private/mesh IPs:

Terminal window
export COMMODORE_URL=http://10.0.1.10:18001
export PURSER_URL=http://10.0.1.11:18003

In multi-cluster deployments, each media cluster gets a delegated Bunny DNS zone at {cluster_slug}.{base_domain}:

PatternPurpose
{slug}.{base}Default media-cluster entrypoint via Foghorn
edge.{slug}.{base}Edge pool domain for this cluster
edge-ingest.{slug}.{base}RTMP/E-RTMP/SRT/WHIP ingest for this cluster’s edges
edge-egress.{slug}.{base}Viewer egress for this cluster’s edges
edge-storage.{slug}.{base}Storage-capable edge pool for this cluster
edge-processing.{slug}.{base}Processing-capable edge pool for this cluster
telemetry.{slug}.{base}Cluster-scoped telemetry ingress
chandler.{slug}.{base}Cluster-scoped control helper
foghorn.{slug}.{base}Viewer routing / playback resolution
livepeer.{slug}.{base}Livepeer gateway for this cluster

Navigator creates the Bunny zone, delegates {cluster_slug}.{base_domain} from Cloudflare with NS records, and reconciles each media service as a Bunny A-record set. The zone apex and foghorn.{slug}.{base} both point at the cluster’s assigned virtual Foghorn instance(s), so callers can use the cluster domain as the default playback/routing entrypoint. Records use Bunny geolocation Smart Routing when Quartermaster has node coordinates. Quartermaster remains the health source; Navigator removes unhealthy nodes from the desired record set instead of enabling provider-side health checks.

Media and edge names ALSO publish at global root entrypoints (see Tier-Based URL Surface below). Cluster-concrete records remain as operator-pin / debug surfaces.

HTTP-based protocols can go through Foghorn because Foghorn can return JSON or issue redirects. Non-HTTP protocols connect directly to edge pools because they cannot follow HTTP redirects.

Traffic classDomainRouting behavior
HLS, LL-HLS, DASH, WHEP/WebRTC, MP4, WebM/MKV, TS{slug}.{base} or foghorn.{slug}.{base}Foghorn resolves or redirects
Livepeer gateway APIlivepeer.{slug}.{base}Direct to gateway endpoint
RTMP/E-RTMP/SRT/WHIP ingestedge-ingest.{slug}.{base}Direct to ingest edge pool
RTMP/SRT/RTSP/DTSC playback when exposededge-egress.{slug}.{base}Direct to egress edge pool

Quartermaster is the health source for desired DNS state. Navigator filters unhealthy or addressless nodes before reconciling records; provider-side health checks are an implementation detail of the authoritative provider integration. Use frameworks dns doctor to compare public DNS with Quartermaster inventory.

Each cluster uses a wildcard certificate for its subdomain space:

*.{cluster_slug}.{base_domain}

Certificates are issued via ACME DNS-01 challenges through the provider authoritative for the name. Cloudflare handles root/API/web/admin names; Bunny handles media cluster wildcards such as *.{cluster_slug}.{base_domain}.

Once issued, certificates are distributed to edge nodes via ConfigSeed — Foghorn pushes TLS bundles to Helmsman over the existing gRPC control stream. Edges do not need direct access to the ACME provider.

FrameWorks exposes three URL tiers per service. The webapp and SDKs pick the right one for each tenant; operators see all three in the dashboard.

1. Global root entrypoints — default UX for free / platform-official tenants

Each tenant-aliasable service has a single global record under {base_domain}:

PatternPurpose
foghorn.{base}Global HTTP playback (geo-routed to nearest platform Foghorn)
edge-ingest.{base}Global RTMP/SRT/WHIP ingest (geo-routed to nearest platform edge)
edge-egress.{base}Global viewer egress
edge.{base}Global edge pool
edge-storage.{base}, edge-processing.{base}Storage / processing variants
chandler.{base}Global control helper
livepeer.{base}Global Livepeer gateway

These live as Bunny smart records and resolve to platform_official cluster nodes only (third-party / marketplace / tenant-private edges are excluded from global pools — see “Self-hosted trust boundary” below). Certificates: one pool-assigned multi-SAN cert for foghorn/chandler/livepeer; one platform-edge multi-SAN cert for the five edge-* names. Both distributed via ConfigSeed only to platform-operated nodes.

2. Cluster-concrete URLs — operator pin / debug

Per-cluster names as documented in “Media Cluster DNS” above: {service}.{cluster_slug}.{base}. Always available regardless of tier. Used by self-hosted operators on free tier, by operators wanting to pin traffic to a specific cluster, and by diagnostics.

3. Tenant aliases — paid-tier branded URLs that span subscribed clusters

Paying tenants get a per-tenant alias under the shared Bunny zone cdn.{base}:

PatternPurpose
{tenant}.cdn.{base}Tenant apex
foghorn.{tenant}.cdn.{base}Tenant playback (geo-balances across subscribed clusters of any kind)
edge-ingest.{tenant}.cdn.{base}Tenant ingest (RTMP/SRT/WHIP)
edge-egress.{tenant}.cdn.{base}Tenant egress
edge-storage.{tenant}.cdn.{base}, edge-processing.{tenant}.cdn.{base}Tenant storage / processing
chandler.{tenant}.cdn.{base}, livepeer.{tenant}.cdn.{base}Tenant control helpers

A single per-tenant wildcard cert (*.{tenant}.cdn.{base} plus the apex) covers every service. The cert is distributed via ConfigSeed to every edge in clusters the tenant subscribes to — regardless of cluster kind (platform-official, tenant-private, third-party marketplace). Caddy SNI on each edge presents the right cert per Host header. Bunny smart records under cdn.{base} resolve to the union of edges across the tenant’s subscribed clusters.

This is the marketplace-spanning feature: one URL that geo-balances across whatever capacity the tenant has subscribed to while keeping service identity and certificate distribution tenant-scoped.

StatusMeaning
cert_issuingQuartermaster signaled intent on paid-tier activation; Navigator is running ACME (LE primary, GTS fallback).
cert_issuedCert exists; tenant URLs become visible once Navigator has at least one ACK-gated DNS member.
cert_failedACME error; check last_error. The worker retries on the next reconciliation pass.
tearing_downTenant downgraded / cancelled; Navigator is clearing DNS records and per-edge cert distribution.

Additions are ACK-gated: Helmsman applies the ConfigSeed, Foghorn reports the ACK to Navigator, and Navigator adds only successfully applied edges to Bunny DNS. Removals are DNS-first: Navigator removes the cluster’s edges from Bunny before later ConfigSeeds drop the tenant cert from those edges.

  • Cluster wildcards (*.{cluster_slug}.{base}) and per-tenant wildcards (*.{tenant}.cdn.{base}) are distributed to all edges in the relevant cluster regardless of operator kind. Trust math: the operator only ever sees certs scoped to their own cluster’s namespace or to tenants who explicitly subscribed to them.
  • Global service entrypoints and the platform-edge multi-SAN cert are ONLY distributed to platform_official cluster edges. Third-party / marketplace / tenant-private edges cannot impersonate the global names.
Tenant statePrimary URLDiagnostic / fallback
Free + platform-official onlyGlobal rootCluster-concrete
Free + self-hostedCluster-concrete
Paid (any sub mix)Tenant aliasGlobal root, then cluster-concrete

The Commodore CreateStreamResponse and GraphQL StreamingConfig surface all three tiers ({service}_domain, global_{service}_domain, tenant_{service}_domain). SDK/webapp prefer tenant > global > cluster-concrete.


Navigator needs credentials for the authoritative provider it is expected to manage. For Cloudflare-managed root names, use an API token with:

  • Zone.DNS: Edit
  • Account.Load Balancers: Edit (for multi-node setups)

Core environment variables:

Terminal window
CLOUDFLARE_API_TOKEN="your-api-token"
CLOUDFLARE_ZONE_ID="your-zone-id"
CLOUDFLARE_ACCOUNT_ID="your-account-id"
BUNNY_API_KEY="your-bunny-api-key"
NAVIGATOR_GOOGLE_TRUST_EAB_KID="your-gts-eab-key-id"
NAVIGATOR_GOOGLE_TRUST_EAB_HMAC_KEY="your-gts-eab-hmac-key"

Optional environment variables:

Terminal window
# Cloudflare proxy overrides (comma-separated service types)
NAVIGATOR_PROXY_SERVICES="bridge,chartroom,chatwoot,foredeck,grafana,listmonk,logbook,metabase,steward"
# Certificate issuance
ACME_ENV="production" # or "staging"
NAVIGATOR_CERT_ALLOWED_SUFFIXES="example.com"
NAVIGATOR_ACME_CA_ORDER="letsencrypt,google-trust" # override only