Skip to content

System architecture

CDNFoundry is a modular Laravel monolith surrounded by specialized data-plane services. PostgreSQL stores desired state. PowerDNS data, signed edge artifacts, runtime snapshots, cache contents, ClickHouse events, and aggregates are derived or rebuildable.

Diagram source
flowchart LR
    subgraph Management["Management plane"]
      UI["Panels + API"] --> App["Laravel + workers"]
      App --> State[("PostgreSQL + Valkey")]
      EdgeControl["edge-control"] --> App
    end

    subgraph Runtime["Traffic planes"]
      DNS["DNSdist → PowerDNS"]
      Agent["Edge agent"] --> Edge["Gateway + bounded cells"]
    end

    subgraph Operations["Observability plane"]
      Collect["Vector + exporters"] --> Stores["ClickHouse + Prometheus + Loki"]
      Stores --> Grafana["Grafana"]
    end

    Agent -->|"outbound mTLS"| EdgeControl
    App -->|"revisioned reconciliation"| DNS
    DNS -. "telemetry" .-> Collect
    Edge -. "telemetry" .-> Collect
    State -. "sanitized metadata" .-> Grafana

DNS namespaces and addresses

Namespace or addressOwner and purposeCDNFoundry PowerDNS?
control.<operator-zone>, edge-control.<operator-zone>, telemetry.<operator-zone>, grafana.<operator-zone>, dns-api-N.<operator-zone>Independent external DNS provider; management and recovery reachabilityNever
ns1.<platform-zone>, ns2.<platform-zone> and glueParent/registrar delegation to public DNSdist addressesServed by DNSdist from derived PowerDNS state after bootstrap
Enrolled customer zonesPostgreSQL desired state reconciled into private PowerDNS databasesYes
Edge pool service addressesPublic HTTP/HTTPS addresses selected through platform/customer DNSStored as platform desired state, not management addresses
Private PowerDNS, PostgreSQL, Valkey, ClickHouse, agent/status addressesHost or private service networksNo public DNS required

Avoid a DNS bootstrap loop

Management records must remain resolvable while CDNFoundry DNS is empty, degraded, or being restored. Hosting them in the platform's own PowerDNS can leave the DNS API and control plane unreachable precisely when operators need them for repair.

PlaneComponentsResponsibility
ManagementLaravel, Filament, Horizon, schedulerAuthorization, validation, desired state, operations, reconciliation
Durable control dataPostgreSQL, ValkeyDesired state, audit, operation records, queues, sessions, cache
Authoritative DNSDNSdist, PowerDNS, PowerDNS PostgreSQLPublic DNS ingress and private authoritative answers
Edge HTTPEdge agent, edge gateway, bounded OpenResty cellsArtifact activation, destination/Host/SNI routing, TLS selection, proxying, cache, security
ObservabilityVector, ClickHouse, Prometheus, Alertmanager, GrafanaBounded event delivery, analytics, metrics, alerts, read-only operator diagnosis

Only DNSdist, mapped edge-gateway service listeners, and the browser/API reverse proxy belong on public ingress. Edge control uses mutual TLS. Telemetry and PowerDNS API gateways are source restricted by the production Caddy configuration. Internal databases, Valkey, ClickHouse, raw metrics, Grafana port 3000, and PowerDNS itself remain private. Remote Grafana access uses a deployment-owned authenticated HTTPS proxy or trusted tunnel.

Architectural decisions

PostgreSQL owns intent

The control schema stores what the operator asked for, who may change it, which revision is current, and whether derived targets acknowledged it. PowerDNS tables, artifacts, active edge directories, cache objects, and analytics aggregates can be rebuilt.

Reconciliation owns side effects

Controllers and Filament actions validate, authorize, and commit desired state. They do not call PowerDNS, ACME, an edge, an origin, or ClickHouse synchronously to finish a mutation. Unique jobs coalesce work, skip obsolete revisions, validate candidates, activate atomically, and record receipts.

Data planes remain autonomous

An outage of Laravel, PostgreSQL, Valkey, ClickHouse, or Vector must not stop an already-configured DNS answer or HTTP request. DNSdist and OpenResty operate from private runtime state, and the edge agent retains active and previous snapshots.

Observability is read-only and downstream

Grafana reads Prometheus, bounded ClickHouse telemetry, and a sanitized PostgreSQL view through separate least-privilege accounts. It cannot mutate desired state or ingest traffic. The two provisioned dashboards are diagnostic read models; dashboard or datasource failure cannot affect serving or reconciliation.

Scale uses bounded shared units

Domains are data inside shared DNS and OpenResty runtimes. Scale comes from workers, DNS capacity, telemetry capacity, edge nodes, and bounded cells—not a normal per-domain container, daemon, timer, cache directory, or reload.

Boundary test

If a feature requires Laravel, PostgreSQL, ClickHouse, or an external API during a customer DNS or HTTP request, it violates the serving boundary.

Failure isolation

FailureExisting trafficManagement/recovery
Laravel or PostgreSQL unavailableDNS and HTTP continue from active runtimeUI, mutations, and reconciliation pause
One PowerDNS target failsOther authoritative targets continueFailed target keeps its last valid zone
Invalid edge artifactActive cell continuesCandidate is rejected and failure recorded
ClickHouse or Vector unavailableDNS and HTTP continueAnalytics becomes partial or unavailable
Grafana or Prometheus unavailableDNS and HTTP continueCommand centers or alert evaluation become unavailable; source state is unchanged
Origin unavailableCache/stale policy may serve eligible objectsOrigin health and errors become visible

Continue with Components, Data flows, and Data model. Before allocating production hosts, compare the Production reference architectures.

CDNFoundry documentation