Skip to content

Connecting to the Network

Connecting your edge node is the last setup step. Enrollment registers the node with its cluster’s Foghorn and gives it a node identity, so it can receive traffic and report telemetry.

Terminal window
curl -sSfL https://github.com/Livepeer-FrameWorks/monorepo/releases/latest/download/install.sh | sh

Override the version or install directory with environment variables:

Terminal window
curl -sSfL https://github.com/Livepeer-FrameWorks/monorepo/releases/latest/download/install.sh | \
FRAMEWORKS_VERSION=v1.2.3 FRAMEWORKS_INSTALL_DIR=/usr/local/bin sh

Keep the CLI up to date:

Terminal window
frameworks update

If you’re logged in (frameworks login), deploy an edge node in a single command:

Terminal window
frameworks edge deploy --ssh ubuntu@edge-1 --email [email protected]

This automatically:

  1. Creates a private edge cluster with an assigned Foghorn if you don’t have one
  2. Generates an enrollment token
  3. Pre-registers the edge node through Bridge (assigns domain, ID, Foghorn address, and internal gRPC trust bootstrap)
  4. Runs the full provision pipeline (preflight, tuning, templates, start, verify)

To deploy to a specific cluster:

Terminal window
frameworks edge deploy --cluster-id my-edge-prod --ssh ubuntu@edge-1

The target cluster must already have an assigned Foghorn. If you are starting from scratch, omit --cluster-id and let Bridge create the private edge cluster.

If you prefer step-by-step control, follow the sections below.

You need an edge_node bootstrap token for a cluster that has an assigned Foghorn.

Via Dashboard (tenant owner):

  1. Go to Infrastructure → Clusters
  2. Click Create Edge Cluster
  3. Copy the bootstrap token shown in the modal

Creating the cluster this way assigns it a Foghorn automatically, the same as the one-command CLI path.

If a dashboard-created token fails with Cluster has no Foghorn assignment yet, use frameworks edge deploy without --cluster-id or ask an admin to create a token for an assigned edge cluster.

Via CLI (admin):

Terminal window
frameworks admin bootstrap-tokens create \
--kind edge_node \
--tenant-id <TENANT_UUID> \
--cluster-id <CLUSTER_ID> \
--name "edge-node-1" \
--ttl 24h

By default, bootstrap tokens are single-use. Set --usage-limit if you need a reusable token.

First, add the enrollment token to your .edge-enroll.env (kept separate from .edge.env so token changes never restart an enrolled node):

Terminal window
# In .edge-enroll.env
EDGE_ENROLLMENT_TOKEN=your-enrollment-token

Then start the stack:

Terminal window
frameworks edge enroll --dir /opt/frameworks-edge

This:

  1. Starts the single frameworks-edge container (MistServer, Helmsman, and Caddy under one supervisor)
  2. Waits for https://<EDGE_DOMAIN>/health to become available
  3. Helmsman connects to Foghorn (gRPC) and sends the enrollment token
  4. Foghorn asks Quartermaster to register the node and starts including healthy heartbeats in routing decisions

The enrollment token carries tenant_id and cluster_id, so your node is enrolled into the correct cluster automatically. After Foghorn accepts the registration and returns its first configuration seed, Helmsman durably completes any requested identity rotation and writes a non-secret local receipt. Native installs then overwrite the token value in .edge-enroll.env directly and remove any obsolete cleanup request. In the managed container, Helmsman submits a durable cleanup request and a narrow root supervisor service scrubs the two root-owned bind mounts in place; this expected deferral is logged as a warning, and the host files are never chowned to the container’s numeric service group. A later accepted rotation replaces a stale request atomically. Verify the value is empty after enrollment; if an unmanaged deployment does not expose a writable token file, remove the bearer secret yourself. A previously admitted node can then reconnect from its pinned local admission during a temporary Quartermaster outage. After enrollment, your node appears in the dashboard under Infrastructure → Nodes.

If you used --enrollment-token during frameworks edge init, the CLI sent the token to Bridge’s public bootstrapEdge mutation. Bridge validates the token via Quartermaster, finds the cluster’s assigned Foghorn, and proxies a PreRegisterEdge call. The response carries:

  • Node ID — a stable, unique identifier for your node
  • Edge domain — {node_label}.{cluster_slug}.{base_domain} where node_label is the node ID with a single edge- prefix (Navigator creates the A record)
  • Pool domain — the cluster’s shared edge pool domain
  • Foghorn gRPC address — for Helmsman’s ongoing control stream
  • Internal CA bundle — staged locally so Helmsman can trust internal gRPC before the first control stream connects

The operator only ever needs the token. Bridge is the rendezvous; the cluster’s Foghorn is resolved server-side. After bootstrap, the edge talks directly to its assigned Foghorn — it does not join the internal WireGuard mesh.

Older enrolled nodes may have a stored fingerprint but no Ed25519 node identity key. FrameWorks never accepts or persists a request-supplied key from fingerprint knowledge alone. After the strict control-plane upgrade, the control stream fails with enrollment_token_required until recovery completes; plan this as a brief, per-node maintenance interruption.

Recover the existing node through the enrollment path:

  1. Confirm the node ID, tenant, cluster, and stable hostname/fingerprint match the existing record.
  2. As a tenant owner/admin (or platform operator), issue a new edge_node enrollment token scoped to that tenant and cluster.
  3. Put the token in .edge-enroll.env and set HELMSMAN_ROTATE_NODE_IDENTITY=true for this recovery boot. If the flag is missing, Foghorn returns IDENTITY_ROTATION_REQUIRED; it does not mislabel the accepted token as invalid.
  4. Restart the edge stack. Helmsman generates/loads its local identity key and Foghorn asks Quartermaster to rotate the existing binding under the token transaction.
  5. Verify the node reconnects, then remove the consumed token and unset HELMSMAN_ROTATE_NODE_IDENTITY.

Do not delete the fingerprint row, manually write a public key, or retry without a token. Those shortcuts bypass the ownership proof and are intentionally rejected.

After initial provisioning, certificate renewals are pushed to edge nodes via ConfigSeed — Foghorn sends updated TLS bundles to Helmsman over the existing gRPC control stream. Edges do not need direct access to the ACME provider or Navigator.

Check that your node is talking to the network:

Terminal window
frameworks edge status --dir /opt/frameworks-edge

This shows:

  • Service status for MistServer, Helmsman, and Caddy
  • HTTPS health check against your configured EDGE_DOMAIN

For enrollment and heartbeat status, check the dashboard—your node should appear under Infrastructure → Nodes once enrolled.

Once enrolled, Foghorn (the load balancer) knows about your node. When a viewer requests a stream:

  1. Foghorn checks which nodes have the stream
  2. GeoIP determines the viewer’s location
  3. Scoring weighs node load, viewer proximity, and stream availability
  4. Redirect sends the viewer to the best node (possibly yours)

Your node will receive traffic when:

  • A stream is ingesting to your node
  • Viewers are geographically closer to you than other edges
  • Other edges are overloaded

Streamers can push directly to your node instead of the default ingest. Direct ingest requires MistServer ports to be reachable on the host. On Linux, container mode uses host networking, so all media ports are already bound on the host; on macOS the compose template publishes the media port set (RTMP, SRT, RTSP, WebRTC, HTTP) explicitly. In both cases you only need to open/forward them at your firewall or router.

Open/forward as needed:

  • 1935/tcp (RTMP/E-RTMP ingest)
  • 8889/udp (SRT ingest)
  • 5554/tcp (RTSP)

Caddy listens on 80/443. After ConfigSeed activation, Helmsman rewrites Caddy so HTTP viewer traffic is proxied to MistServer on 8080.

Direct RTMP/E-RTMP ingest:

rtmp://stream.yourdomain.com:1935/live/{stream-key}

Or use the network’s default ingest and let Foghorn route:

rtmp://edge-ingest.frameworks.network:1935/live/{stream-key}

Both work. Direct ingest means lower latency to your node; network ingest means Foghorn picks the best ingest point.

Your node advertises what it can do. Set these in .edge.env, which the compose file already loads into the single edge container, then recreate that service with docker compose -f docker-compose.edge.yml up -d edge so it picks up the new values (docker compose restart does not re-read env files):

Terminal window
# In .edge.env
HELMSMAN_CAP_INGEST=true # Can receive RTMP/E-RTMP/SRT streams
HELMSMAN_CAP_EDGE=true # Can serve viewers
HELMSMAN_CAP_STORAGE=true # Can store recordings
HELMSMAN_CAP_PROCESSING=true # Can transcode

Disable capabilities you don’t want:

Terminal window
# Viewer-only node (no ingest)
HELMSMAN_CAP_INGEST=false
# Ingest-only node (no viewers)
HELMSMAN_CAP_EDGE=false

To stop receiving network traffic:

Terminal window
cd /opt/frameworks-edge
docker compose -f docker-compose.edge.yml down

When Helmsman stops, Foghorn stops receiving heartbeats. Foghorn’s health sync reports only nodes seen alive within the last 90 seconds, so stale nodes are excluded from routing while their registry entry is retained.

“Invalid token”

The token was already used or expired. Get a fresh one.

“Network unreachable”

Your server can’t reach the control plane. Check firewalls, DNS, and outbound HTTPS.

“Node already enrolled”

This usually means the node already has an identity. You can just start the stack again—no re‑enrollment required. If you need to move the node to a different cluster, revoke the old token, create a new one, and enroll again.

Node shows offline in dashboard

Helmsman isn’t sending heartbeats.

Terminal window
# Check Helmsman logs
frameworks edge logs helmsman --tail 50

Your node is connected. Learn how to manage it day-to-day.