Run the service
Install, foreground-launch, healthz — thirty seconds below. Then runbook, knobs, security model, REST contract, and debugging in the pages that follow.
30-second start
Have Netlab installed?
The launcher refuses to start if netlab isn’t on PATH. If your host is fresh, run Netlab host setup first — rootless Netlab + Containerlab on Ubuntu in about 20 minutes — then come back here.
Install the CLI in an isolated environment:
uv tool install drops the CLI in ~/.local/bin (or uv tool dir) inside an isolated environment that uv manages.
pipx installs into a per-app virtualenv under ~/.local/pipx/venvs/. After the first install, run pipx ensurepath and re-login so ~/.local/bin is on PATH.
Start the server in the foreground:
You’ll see the lifespan startup sequence — single-instance lock, Netlab CLI check, Uvicorn bind. If neops-remote-lab isn’t on PATH, the install hasn’t put it there yet — run uv tool update-shell, pipx ensurepath, or re-login depending on which installer you used.
In a second terminal, hit the liveness probe:
204 No Content is the liveness signal. Anything else — connection error, 502, redirect — means the server didn’t bind, the port is taken, or your firewall is blocking loopback. Fix transport before continuing; the lab API can’t compensate.
No HTTP authentication
neops-remote-lab ships without bearer-token, OAuth, or mTLS authentication. The only access boundary on /lab/* is the X-Session-ID of an ACTIVE session. Deploy behind a VPN. See Security model for the full posture.
What’s running, exactly
The server has done four things on startup:
- Acquired the single-instance filelock under
/tmp/. - Probed for
netlabonPATH— refused to start without it. - Cleaned up any stale
defaultNetlab instance left from a previous crash. - Bound Uvicorn on
0.0.0.0:8000.
It’s now waiting for POST /session.
In this section
-
Install via uv/pipx, run under
systemd, recover from a stale filelock, unstick a wedged lab. -
CLI flags (
--host,--port,--debug,--log-level,--log-config) and theNEOPS_NETLAB_STREAM_OUTPUTenv var. Client config lives under Use from Python. -
What the X-Session-ID gate does and doesn’t protect against; the do/don’t operational guidance; controls to layer on if you must expose the service.
-
Endpoint-by-endpoint contract: schema, error codes, the
X-Session-IDmatrix, and a cURL example for each. -
Symptom/cause/fix table, common HTTP error codes, client and server log patterns, the
/debug/healthendpoint, stale-state recovery. The page to grep when something breaks.
What to read next
- Architecture — why the service is shaped the way it is; the three cooperating components; the one-server-per-host and one-lab-per-host invariants.
- Session queue — the FIFO model that the
X-Session-IDaccess boundary enforces. - Netlab host setup — must be complete before the server will start; the launcher exits if
netlabis not onPATH. - Headscale: quick — the recommended VPN enclosure for the internal-trust HTTP surface (alternatives in the page’s Other approaches section).
- Wire into CI — wire the service into GitHub Actions, GitLab CI, or Jenkins.