One line on Ubuntu. One compose file anywhere else.
Three ways in, and one fact about your host picks it. The shell installer wants Ubuntu 24.04 or 26.04 and the ISO brings its own; Docker runs on any distribution, which is also the answer on Ubuntu 26.04 — resolute ships Python 3.14 and does not package Guacamole, so the native install has nothing to build against. No signup, no key, nothing to register.
Whichever you pick: the RDMA lab alone wants Linux 7.1+ on the host, where rdma_rxe gained its per-namespace UDP 4791 socket. Below that it starts and moves no data, and says so on first run. Detail and the check.
On 26.04 there is no RDP console. Ubuntu stopped packaging Guacamole after 24.04, so Labtris builds guacd from source there, and 1.6.0 does not compile against FreeRDP 3 — the only FreeRDP 26.04 ships. VNC, SSH and telnet consoles all work, and QEMU consoles are VNC. It only bites if you connect to a Windows guest over RDP, in which case use 24.04 or the compose install, which pulls a prebuilt guacd with RDP in it.
On a fresh Ubuntu 24.04 or 26.04 host
Runs about five minutes and finishes with the URL to open, where the config lives, and where the generated database password sits. Idempotent — re-run to upgrade.
curl -fsSL https://labtris.com/install | sudo LABTRIS_TOKEN=github_pat_… bashLABTRIS_TOKEN is the GitHub token from your access invitation; the installer sends it as a header on the clone and writes it nowhere on the host, so the upgrade command needs it again. GH_TOKEN and GITHUB_TOKEN are read as well.- Refuses to run on anything but Ubuntu 24.04 or 26.04 x86_64 (override with
LABTRIS_FORCE_OS=1). - Installs
git,curl,ca-certificates. - Clones the repository to
/opt/labtris, using the token for that one request. - Hands off to
packaging/install-labtris.sh, which sets up Postgres, the service user, systemd units, nginx, everything. - Prints a summary block and writes
/root/labtris-install-summary.txt.
sudo bash is a trust exercise. The installer at /install is get.sh from the repository, served here unchanged — kept tiny and readable on purpose. The real installer, packaging/install-labtris.sh, is in the clone it makes; read it there before the hand-off if you want to.One compose file, any Linux host
No distribution requirement at all. Verified on Ubuntu 24.04 and 26.04; Debian, RHEL, Arch, Alpine and anything else with a working Docker are expected to be fine but are not ones we run. Only the RDMA lab cares what is underneath, and only about the kernel version, not the distribution. Docker and a working /dev/kvm are the only two things it asks for. Nothing is cloned — the compose file is served from this site and the image from GitHub’s registry — and upgrading is a tag bump rather than a reinstall. If the pull is refused, log in to ghcr.io with your GitHub username and the token from your invitation first.
curl -fsSL https://labtris.com/compose | docker compose -f - up -d- Every Labtris process shares one private container namespace, so lab bridges, taps and nftables rules land there — the host’s own networking is untouched.
- Container nodes run on a private Docker daemon, not the host’s socket.
- Ports publish on
127.0.0.1by default; widen withLABTRIS_BINDonce you have an admin account. - Two things it can’t do, because of that isolation: cloud networks that put a lab on a physical segment, and the settings that rewrite the host’s netplan.
/dev/kvm to hand it, and the container would be sharing a namespace inside Docker’s own Linux VM rather than your machine. Run a Linux VM instead.Bootable ISO for bare metal or air-gapped
Every Debian package, every Python wheel and the built interface baked in — nothing fetched during install. 3.8 GB as of 0.12.0, so GitHub’s 2 GiB asset cap splits it in two. BIOS and UEFI both boot from the same image.
# the two parts + checksum arrive with your access invitation
# substitute the version you downloaded
cat labtris-0.13.9-amd64.iso.part-* > labtris-0.13.9-amd64.iso
sha256sum -c labtris-0.13.9-amd64.sha256ghcr.io/labtris/uet-ref and ghcr.io/labtris/rdma-host are published by CI, the rest come from Docker Hub. Nothing to build first.docker pull fails with “no matching manifest for linux/arm64/v8”; add --platform linux/amd64 to inspect one. Labtris itself needs a Linux host with KVM, so arm64 would mean the whole set, not just a node image — say so if you need it.One command, with a backup taken first.
Goes to the latest release, dumps the database before it migrates anything, and tells you whether the result is actually serving. Your labs, pods, images and database are carried across, not replaced.
curl -fsSL https://labtris.com/upgrade | sudo LABTRIS_TOKEN=github_pat_… bashA specific release instead: … | sudo bash -s -- --to v0.12.0. To see what it would do and change nothing: … | sudo bash -s -- --check. The -s -- matters — without it bash takes the flags for itself rather than passing them on.
--depth 1 clone has no tags locally and sorting them as text puts v0.9.0 above v0.12.0. Then pg_dump to /var/backups/labtris — always, with no flag to skip, because alembic upgrade head is not reversible. Then fetch, check out, reinstall dependencies, migrate, restart. Then it verifies labtris-api and labtris-netd are active and the interface answers, and on failure prints the journal command, the previous commit and the path to the dump.docker compose pull && docker compose up -dWhere to look when something breaks.
| Shell installer or ISO | Docker | |
|---|---|---|
| Web UI | https://<host>/ (also :8081, plain HTTP) | http://<host>:8080 |
| Config | /etc/labtris/labtris.env | environment: in docker-compose.yml |
| DB password | /etc/labtris/db-password | set in docker-compose.yml |
| Health check | labtris system doctor | docker compose exec api labtris system doctor |
| Logs | journalctl -u labtris-api -u labtris-netd -f | docker compose logs -f api netd |
| Restart | systemctl restart labtris-api labtris-netd | docker compose restart |
The full handbook lives at docs.labtris.com.