# Architecture

> How Falak's control plane, agents, builder, edge and observability stack fit together, which ports they use, and how data flows between them.

Source: https://falak.sh/docs/concepts/architecture/

This page describes every moving part of a Falak installation and how they communicate. Read it when you plan a production setup, debug connectivity, or review security.

## Components

| Component | Where it runs | What it does |
|---|---|---|
| **Control plane** | One host, as a Docker Compose stack in `/opt/falak` | Laravel 12 app with the UI (Inertia + React), the REST API, the agent API, the build queue, alerting and Insights. Stores state in PostgreSQL 17 and Valkey. |
| **Edge** | On the control plane host (`edge` service, Caddy) | Terminates TLS for the panel (Let's Encrypt) and for the agent API (Falak's own CA, mutual TLS). |
| **Builder** | On the control plane host (`builder` service), and optionally on `builder` servers | `falak-builder serve` long-polls the control plane for build jobs, clones your repository, builds, and uploads an artifact or pushes an image. |
| **Agent** | On every managed server (`falak-agent`, systemd) | Enrolls with a one-time token, then long-polls for commands, runs them, streams output, sends heartbeats every 15 s, supervises processes and cron, and relays telemetry. |
| **Caddy / FrankenPHP** | On servers that serve HTTP | Serves your sites. FrankenPHP embeds Caddy and runs PHP; PHP-FPM servers and load balancers get a standalone Caddy. The agent configures it through the Caddy admin API on `127.0.0.1:2019`. |
| **Observability stack** (optional) | On the control plane host with `--observability` | Loki (logs), Tempo (traces), VictoriaMetrics (metrics), Grafana (dashboards) and an OTLP gateway. |
| **`falak` CLI** | Your computer or CI | Talks to the public REST API with a bearer token. |

## Control plane services

The Compose project `falak` contains these services:

| Service | Role |
|---|---|
| `control-plane` | The panel and REST API (FrankenPHP in worker mode) |
| `agent-api` | Agent endpoints (`/agent/*`), installer (`/install/*`) and builder API (`/api/internal/*`), in classic PHP mode with its own thread pool |
| `horizon` | Queue workers (deployments, provisioning, alert delivery, …) |
| `reverb` | WebSockets for live updates in the UI |
| `scheduler` | Runs `schedule:run` every minute |
| `postgres` | PostgreSQL 17 |
| `valkey` | Cache, queues, sessions, agent wake-ups |
| `edge` | Caddy with Let's Encrypt and mTLS |
| `builder` | `falak-builder serve` for native builds |
| `gateway`, `loki`, `tempo`, `victoriametrics`, `grafana` | Only with the `observability` profile |

## Network flows

```text title="Who talks to whom"
browser ──HTTPS 443──► edge ──► control-plane (UI, API)      wss://<panel>/app/… ──► reverb
falak CLI / CI ──HTTPS──► edge ──► control-plane (/api/v1)
GitHub/GitLab/Bitbucket ──HTTPS webhooks──► edge ──► control-plane (/api/webhooks/…)

falak-agent ──HTTPS + client cert──► agents.<panel> ──► agent-api (/agent/v1)     (outbound from servers)
falak-agent ──HTTPS──► <panel>/install/agent/…   (agent binary download, upgrades)
falak-agent ──HTTPS──► <panel>/api/internal/artifacts/… or S3   (release artifacts)
falak-agent ──OTLP/HTTP──► <panel>/otlp ──► gateway ──► Loki · Tempo · VictoriaMetrics

builder ──HTTPS──► <panel>/api/internal/builds/next   (long-poll for jobs)
builder ──git clone──► your git provider
```

Servers never need inbound connections from the control plane. The agent **dials out**; SSH stays available as your own fallback.

## The agent protocol

- **Transport:** HTTPS with mutual TLS. The control plane runs an internal certificate authority, the **Fleet CA**. Agent certificates are valid for 90 days and renew automatically; the CA is valid for 10 years.
- **Enrollment:** the install command downloads the agent, then `POST /agent/v1/enroll` with the one-time token, a CSR and host facts. The agent receives a signed certificate and an agent id.
- **Commands:** the agent long-polls `GET /agent/v1/commands?wait=30`. Commands are idempotent and carry a JSON-Schema-validated payload. State-style commands (`*.apply`) send the full desired state, and the agent converges to it.
- **Results:** `POST /agent/v1/commands/{id}/events` with batched NDJSON events (`started`, `output`, `progress`, `finished`).
- **Heartbeat:** `POST /agent/v1/heartbeat` every 15 s with facts and a metrics summary. An agent is **offline** after 60 s of silence.
- **Restarts:** each agent process sends a session id. Commands delivered to a previous process are re-delivered when they are safe to repeat (Caddy routes, processes, cron, firewall, telemetry), otherwise failed with "The agent restarted before running the command". A command never acknowledged is handled the same way after a 90 s lease.

Command namespaces: `system`, `provision`, `runtime`, `edge`, `deploy`, `proc`, `cron`, `db`, `net`, `docker`, `telemetry`, `terminal`.

## Data flow of a deployment

```text title="One deployment, three servers"
control plane ──job──► builder: clone, install, build ──artifact──► storage
control plane ──deploy.fetch──► every server (download + unpack release)
control plane ──deploy.prepare──► every server (.env, shared paths, permissions)
control plane ──deploy hook (migrate)──► leader only
control plane ──deploy.activate──► every server (switch current symlink, reload)
control plane ──proc.apply──► every server (restart workers, Octane, …)
control plane ──HTTP health check──► every server
```

Details: [Deployments and releases](/docs/concepts/deployments-and-releases/).

## Telemetry path

Telemetry does not pass through the control plane database:

```text
your app ──(falak/apm-laravel | @falak/apm-node)──► unix:/run/falak/otlp.sock or 127.0.0.1:4318
host metrics, log files, container logs ─────────► falak-agent (batch, retry, disk buffer)
falak-agent ──OTLP/HTTP──► Loki · Tempo · VictoriaMetrics ──► Grafana and the Falak UI
falak-agent ──exceptions, threshold breaches, cron heartbeats──► control plane (Insights)
```

## Where things live

| Location | Contents |
|---|---|
| `/opt/falak` (control plane host) | `.env`, `custom.env`, `deploy/`, `observability/`, `backups/` |
| `/srv/falak/sites/<site>` (servers) | `releases/`, `shared/`, `current` symlink |
| `/etc/falak` (servers) | Agent key and certificate, CA certificate, agent config |
| `/var/log/falak` (servers) | Supervised program logs, `access/<site>.log` edge access logs |

The full list is in [Ports and file paths](/docs/reference/ports-and-paths/).

## Next steps
