Skip to content

Control Plane & Orchestration

The media plane moves frames; the control plane decides what runs. Operators design a system visually, it’s saved as version-controlled configuration, and the platform makes reality match — starting, stopping, and reconfiguring services across every node, then reporting back what’s actually running.

Control plane — design, deploy, observe web-ui /architectdesign · operate servicesconfig · MQTTRBAC · Lua node-orchestratorreconcile vs Docker running containersinput-proc · mixersoutput-proc desired state(MQTT) start / stopconfigure actual state (MQTT) → mirrors → UI configs are version-controlled in GitLab — a commit triggers CI/CD to deploy the change


A software-defined facility is only as good as its control. Phrame treats the whole system as declared configuration, not hand-wired boxes:

  • Design it visually. Build a media system on a drag-and-drop canvas — components, settings, connections — no config files by hand.
  • Everything is versioned. Configuration lives in GitLab; every change is reviewable, revertible, and auditable. A commit is a deployment.
  • Reality converges on intent. You declare the desired state; the platform reconciles the running containers to match, on every node.
  • Always observable. The actual running state is published back continuously, so the UI always shows what is really happening.

In one line: describe the system you want; Phrame deploys it, keeps it running, and tells you the truth about it.


There are two planes of state, both carried over MQTT:

  1. Desired state — what should be running, authored in the UI.
  2. Actual state — what is running, reported by each node.

The flow around the loop:

  • Design / operate. The architect (drag-and-drop system designer) and the web UI are where you compose and drive pipelines. Architect serialises the canvas straight into the existing module schemas — what it produces is exactly what the processors consume.
  • Store & publish. Configuration is saved through phrame-config into GitLab (with locking), and published as desired state on the broker. A commit triggers CI/CD to deploy.
  • Reconcile. On each node, the node-orchestrator watches the desired state and converges the local Docker daemon to match — starting, stopping, and reconfiguring input-processor, vision-mixers, output-processor, and the rest.
  • Observe. Each node publishes actual state back; mirrors aggregate it into JSON snapshots the UI can query — closing the loop.

Supporting services around the pipeline: phrame-config (versioned config store), the MQTT broker, rbac-api (access control), lua-engine (routing / scripting), mqtt-monitor and stats-monitor (observability), and envoy (reverse proxy).


  • Deployment and reconciliation — how desired state actually becomes running containers, who decides which node runs what, and how the platform reports back what it really has — is covered in its own section: Orchestration & Deployment. In brief: the node-controller converges local Docker on every host, the reconciler decides placement and commits it to Git, and config-sync distributes the configuration as retained MQTT topics.
  • Configuration is environment-driven (PHRAME_ prefix): desired/actual MQTT URLs, OAuth2 endpoint and client creds, status/heartbeat cadences, registry credentials, Docker socket, and TLS cert paths.
  • phrame-config edit flow: acquire a Redis lock (30-min TTL) → edit (Monaco) → save (verifies lock) → commit/push to GitLab → release lock; the commit triggers the deploy pipeline. State: SQLite (users), Redis (sessions + distributed file locks), Socket.io (lock broadcast).
  • Pin identity: streams are addressed as vdi://<uuid>:<suffix> (:0 video, :1 audio), so architect’s wiring maps directly onto bus streams.

The two-plane, reconcile-and-report design is what makes the control plane orthogonal to the media plane: you can redesign and redeploy the production without disturbing the frames already in flight.