ghcr.io/stoutdata/stout:latest, container name stout) on top so the box can heartbeat to the control plane, accept dispatched jobs, and report its capabilities.
Registering a box
From Boxes → Add Box:- Enter the box’s name and IP address. The IP must be reachable from the control plane (typically over a VPN, Tailscale, or a private network).
- Stout generates a one-time setup command you run on the box over SSH. This command contacts the control plane, receives a fresh API key, and installs the
stoutcontainer. - The control plane also pushes an SSH public key into
/etc/lager/authorized_keys.d/stout-control-plane.puband writes/etc/lager/control_plane.jsonon the box. Both need world-writable permissions (chmod 777) for the sync to succeed. - Within a few seconds the box reports its first heartbeat. The fleet view flips it from provisioning to online.
- Port 5000 on the box is reachable from the control plane (the install’s Phase 1 writes config there).
/etc/lagerand/etc/lager/authorized_keys.d/are mode 777. The container runs aswww-dataand needs to create the stout-control-plane public key file.- The control plane has
SSH_PRIVATE_KEYset. Without it, Phase 2 skips the container pull.
The fleet view
Boxes lists every registered box with filters by status, group, and heartbeat age. Click a row to open the detail view, which is organized into four tabs:- Overview — hardware specs from the heartbeat (model, CPU, memory, Lager version), lock status, recent job history.
- Nets — the list of configured nets pulled from
/etc/lager/saved_nets.json, with each net’s role (power-supply, uart, oscilloscope, etc.) and the device behind it. - Webcams — live streams from any USB cameras the box exposes. Useful for bench-watching long-running tests.
- Settings — per-box configuration: name, description, IP address, API key rotation, and access control (which members and teams can dispatch to this box).
Box groups
From Boxes → Groups, create a named group (name, slug, color). Groups are purely organizational — they don’t change what a box can do, but they let you:- Filter the fleet view to one group at a time.
- Grant a team access to a whole group instead of box-by-box.
- Target a workflow at “any box in group X” rather than naming a specific box.
Maintenance windows
From a box’s detail page, open Maintenance → Schedule. Maintenance windows:- Prevent new jobs from being dispatched to the box during the window.
- Do not cancel in-flight jobs — pick your window accordingly.
- Show up in the fleet view with a “maintenance” badge.
- Are recorded in the audit log so nobody wonders why jobs started failing silently.
Box locking
Two flavors of lock coexist:- Manual lock — an admin clicks Lock on the box detail page, optionally with a note (e.g., “I’m debugging the PSU firmware”). Other users see the lock owner and can’t submit jobs.
- Command lock — implicit, short-lived, set by the Lager CLI when running an interactive command. Released on context exit.
Boxes tab deeper content
Deeper coverage of instruments, nets, and the SSH key sync lives in the Lager docs. Stout’s job stops at the boundary: we manage fleets; Lager drives the hardware.Lager: adding instruments
How to physically wire an instrument to a box and declare a net for it.
Lager: interacting with nets
The
lager CLI commands and the Python API for controlling devices by net name.