Labtris
Features

Every feature that ships today.

Grouped by what each one is for. The roadmap and design intent live in the handbook's design notes. Everything below is real — you can install it right now.

Runtime

Nodes

Two kinds of node. Which one you want depends on how the software is shipped, not on preference.

Docker containersAnything shipped as an image. Starts in a second, costs tens of MB, runs FRR, SR Linux, XRd, cEOS, plain Linux hosts.
QEMU virtual machinesAnything shipped as a disk. Vendor appliances, Windows, BSD. Real savevm/loadvm snapshots. KVM where the host has it.
Companion BIOS + CD-ROM per templateSome appliances (NX-OSv 9000, cat9kv, vJunos-EVO, uccx) need a specific BIOS or a CD-ROM to boot. Attach both per template.
Cold-plug NICsEvery interface a node knows about boots with the guest as a real -netdev tap. Vendor appliances that enumerate PCI once at boot (NX-OS, PAN-OS) see all their interfaces.
Editable templatesRAM, CPUs, NIC model, disk bus, iface scheme, description — everything set at import time is a pencil-icon away in the palette.
Bring your own imagesQEMU images are yours. The catalogue records where each one came from so you know where to look. No vendor images ship with Labtris.
GNS3 registry importer228 GNS3 appliance definitions import as templates. Correct RAM, NIC model, disk bus, console type, download URL — no re-authoring per image.
Networking

Wires and segments

Real kernel networking. Nothing is simulated, which is why what you learn in a lab transfers.

Point-to-point linksDrag from one port to another. Creates a veth pair, puts one end in each node's namespace, joins them through a bridge.
Internal bridge segmentsPlain L2, lab-only. No host address, no uplink, no way out.
NAT segments with DHCPBridge with gateway + masquerade + DHCP server + reservations. Guests reach the outside; nothing outside reaches in.
Cloud (host NIC)Attach the lab to a real wire. Picks a NIC or a host-owned bridge. Refuses the management NIC unless explicitly overridden.
VXLAN across hostsOne segment spanning several machines, so a topology bigger than one host is still one topology.
VLAN filtering802.1Q or QinQ. Access ports and trunk ports as first-class objects, re-applied every boot because a port is a fresh veth every time.
netem impairment per directionDelay, jitter, loss, reordering, rate — applied to each direction's own tap. 200 ms one-way is a different experiment from 200 ms symmetric.
Admin-down that unplugs the cableQMP set_link alongside the host tap flip, so the guest driver raises the expected link-down interrupt.
Consoles

Getting inside a node

Serial from the first byte of boot, container shells over a real PTY, VNC and RDP for graphical guests.

QEMU serial consoleFull boot log, kernel messages, single-user mode. Raw bytes — no CRLF injection, no control-frame contamination.
Container PTY consoleReal terminal, docker exec, resizable, correct colour handling.
VNC + RDP through GuacamoleHTML5, no plugin. Force-shared display so a same-tab reconnect works. Tunnel flushed before reopening.
Dock, split, pop-outTerminals dock at the bottom, split side by side, or pop out to their own window. Layout persists across reloads.
Observability

Seeing what happened

Capture, address discovery, and the honest "we don't know" that keeps you from debugging a healthy node.

tcpdump on any link with a BPF filterFilter at capture time, not client-side. Downloads as pcap.
Wireshark GUI streamed to your browserThe real Wireshark binary runs on the lab host under Xvfb + x11vnc, tunneled through the same guacd. Real dissectors, no plugin.
Addressing overlayEvery running guest is asked what addresses it has. Three states — stopped, no agent to ask, no address — because conflating them sends people to debug a healthy node.
Scale

One host, many nodes

The ceilings are not CPU or RAM. They're the knobs Ubuntu ships stock. Labtris tunes them.

KSM (Kernel Samepage Merging)Tuned in, aggressive, measured 8.5:1 dedup ratio across a mixed VM workload — 62 GiB deduplicated on the reference host.
Raised file descriptors1024 → 1048576. Each tap + monitor + console eats FDs; stock defaults die at a few hundred nodes.
Raised ARP table128 / 512 / 1024 → 4× each. Stock defaults produce silent, intermittent L2 blackholing on big topologies.
Tuned swappiness + hugepagesSwapping guest RAM destroys density. THP in madvise mode; static hugetlb reserved only where profiles ask for it.
Multi-host with VXLAN overlayRegister a second host, wire nodes across them, VXLAN builds the tunnel.
Users

Accounts and access

Two roles, add and remove from the UI, admin-only. Every API and WebSocket path authenticates.

First-run admin creationFirst visit asks you to create an administrator. Until you do, anyone who can reach the port can claim it.
Two roles: admin, userAdmins do everything and see every lab. Users see their own. Ownership is what protects.
Settings → UsersAdd, remove, list, promote. From the UI, admin-only.
API

REST, WebSocket, MCP

Everything the interface does, it does over the same HTTP API you can use. There is no private back channel.

REST + OpenAPI at /docsEvery route, every field, with a Try-It button. Same URLs the browser calls.
WebSocket for all stateCanvas, console, capture, assistant, lab-state. Never poll. All authenticated at the handshake.
MCP server22 tools — Looking, Building, Running, Investigating, Removing. Point Claude Code, Cursor, or your own MCP client at it.
Legacy .unl importerImport EVE-NG topologies. Templates map onto the QEMU catalogue; vendor appliances become placeholders with warnings.
Containerlab .clab.yml importerKind + image inheritance handled the way containerlab does it. Bridge / ovs-bridge nodes become segments.
Assistant

An LLM in the room

A chat pane in the interface that can drive the lab. Your key stays in your browser, or the server holds it — your choice.

Bring your own keyOpenAI-compatible base URL, key, and model in Settings → Assistant. Conversation runs client-side against your provider. Labtris never sees the key.
Server-held key fallbackSet LABTRIS_LLM_API_KEY in the env and every user shares one instance and one bill. Browser prefers its own key and falls back to the server's.
Streamed tokens + tool visibilityText arrives token-by-token. Each tool call renders its own bubble with the arguments and result — no folded-away batch at the end.
Consent for destructive toolsdelete_lab, delete_node, stop_node, create_network, join_network pause the loop and ask before firing.
Attach images and PDFsVision-capable models see attachments directly. PDFs render server-side to per-page PNGs (first five pages) so the model always sees the same shape.
Operations

Running the server

curl | bash on Ubuntu 24.04, or an ISO for bare metal. Everything else is idempotent.

One-line installcurl -fsSL https://labtris.com/install | sudo bash on a fresh Ubuntu 24.04. Five minutes, finishes with a summary block.
Bootable ISO for air-gapped installs3.2 GB image with every package, wheel and the built interface baked in. Nothing fetched during install.
Backup and restoreEvery lab plus the instance's settings as one .tar.gz. Restore is additive — never silently deletes.
Google Drive integrationOAuth device flow, drive.file scope only, refresh token stored server-side.
Feedback flagClick a broken thing, describe what should have happened. Report carries the element, its state, the viewport, and a rolling buffer of console errors captured before you clicked.

Everything above is a `curl | bash` away.