Infrastructure
How nodes work
Enrollment, heartbeats, capacity, and drain.
#Enrollment

An admin creates the node, which returns the node record plus a token in id.secret form. Beacon starts with DAEMON_NODE_ID, DAEMON_NODE_TOKEN, and PANEL_API_URL — all three or none — pairs with the panel, syncs its server list, and falls back to its disk cache when the panel is unreachable. Tokens rotate; leaked tokens are revoked, never reused.
#Heartbeats and health
Beacon reports every 30 seconds: version, OS, CPU, memory, disk, runtime status, load, and uptime. Capacity fields are pointers — an unread value is omitted, never zero, so unknown never looks like empty. Desired state is active, maintenance, or draining; actual state is online, degraded, offline, or reconciling; heartbeat rollups add healthy, suspected, unreachable, and recovering. Health scores average only known signals; unknown is excluded, not averaged as zero.
Health loop
#Capacity and drain
Capacity snapshots track totals, allocated, reserved, and available CPU, memory, and disk per node, preferring heartbeat-reported totals over admin-entered ones. Placement refuses nodes with unknown totals. Draining, maintenance, join, and leave are explicit transitions with node events; a draining node takes no new work while existing work evacuates.
POST /nodes create → {node, token}
POST /nodes/:id/rotate-token rotate credential
POST /nodes/:id/heartbeat beacon heartbeat
POST /nodes/:id/drain|cancel drain control
POST /nodes/:id/maintenance maintenance mode
GET /nodes/:id/lifecycle|health|capacity|evacuation-preview