Install on Linux
Install the Roomler agent on Linux with one command — as a root systemd service or a per-user unit — including headless servers, containers and cluster nodes.
Linux is the most flexible of the three platforms and the one most often installed on a machine with no desktop session at all. Both cases work; they just want different flags.
Pick a service mode first
| Mode | Flag | Runs as | Use it for |
|---|---|---|---|
| System | --system |
root, systemd system unit | Servers, headless boxes, cluster nodes, containers, and desktops that should be on the private network from boot |
| Per user | (default) | you, systemd user unit | Desktops where you want to share the session you are actually logged into |
On a desktop, either works
The per-user unit shares the session you are logged into, on any desktop. A system install also shows a GNOME or KDE desktop by itself, while the person signed in there is at the screen, the session is unlocked, and they can be told who is viewing. It never shows the login or lock screen on its own. Only a system install puts the machine on the private network with its own adapter.
To make an installed machine a system service later, enroll the root daemon, then register it:
sudo roomlerd --config /etc/roomler/config.toml enroll --server https://roomler.ai --token <token> --name "$(hostname)"
sudo roomlerd service install --as-service # alias: --systemIt refuses until that config exists, and it says so if a per-user daemon also
runs on the machine: one daemon per machine is the rule, so stop the per-user
unit as that account (systemctl --user disable --now roomler.service).
Install
On a desktop, Roomler Setup needs no token. It does need WebKitGTK 4.1,
which not every desktop has: sudo apt install libwebkit2gtk-4.1-0 on Ubuntu and
Debian, sudo dnf install webkit2gtk4.1 on Fedora. Without it the wizard stops
before its window opens. From a terminal it says error while loading shared libraries: libwebkit2gtk-4.1.so.0; opened from the file manager, nothing appears at
all. The terminal install below needs nothing first.
Download Roomler Setup for Linux, x86_64 or
ARM64 (aarch64) (uname -m tells you
which), unpack it and run roomler-setup:
- Be accessed — system service is already selected. Change it if you want this user only, then continue to Join your organization.
- Click Set up in the browser. The wizard shows a code of eight letters.
- Open roomler.ai/pair, sign in or create an account, type the code, check the device the page shows, pick your organization and click Approve.
- Go back to the wizard. It names who approved the device and into which organization. Click Install and answer the password prompt.
A code lasts 15 minutes. When it runs out the wizard says so, and Start again gives you a new one. A mistyped code only gets “No pending pairing with that code”.
From a terminal, mint a token under Devices → Enroll device, then:
Headless server / cluster node — root systemd service:
curl -fsSL https://roomler.ai/api/setup/install.sh | sh -s -- \
--role daemon --system --token <token> --server https://roomler.ai --name "$(hostname)"Desktop — per-user unit:
curl -fsSL https://roomler.ai/api/setup/install.sh | sh -s -- \
--role daemon --token <token> --server https://roomler.ai --name "$(hostname)"Tunnels only — just the CLI, no agent:
curl -fsSL https://roomler.ai/api/setup/install.sh | sh -s -- \
--role tunnel --token <token> --server https://roomler.ai --name "My laptop"The script installs the .deb on Debian and Ubuntu derivatives — x86_64 and
arm64 — or a tarball elsewhere, verifies the SHA-256, enrolls the machine, and
enables the unit.
Useful flags:
| Flag | Effect |
|---|---|
--download-only |
Fetch and verify the artifact, install nothing |
--no-enroll |
Install and set up the service, but skip enrollment (do it later) |
--server <url> |
Point at a self-hosted server instead of roomler.ai |
--uninstall |
Remove Roomler from the machine — see Uninstall |
Check it came up
roomler status # per-user install
sudo roomler status # system install`systemctl is-active` can lie on a system install
A machine that was enrolled before the current config convention can end up
running a perfectly healthy daemon that systemd does not own. systemctl is-active then reads inactive while the device is online and answering.
Check pgrep -x roomlerd and roomler peers before concluding anything is
wrong — and in particular, do not “restart to fix” on that basis.
Headless machines
A server with no display can still be reached as a desktop: the agent’s virtual-display mode gives the machine a screen, so View screen drops you into a live console rather than failing. Enable it in the device’s configuration rather than by an environment variable, so the setting survives a reboot and applies to a daemon started outside systemd.
Wayland and X11 desktops are both supported for capture and input, with different backends underneath. Which one applies is detected at session time — see per-OS permissions.
Where things live
| Item | Path |
|---|---|
| System config | /etc/roomler/config.toml |
| Per-user config | ~/.config/roomler/config.toml |
| Binaries | /usr/bin/roomlerd, /usr/bin/roomler |
| Logs | journalctl -u roomlerd (system) or journalctl --user -u roomler (per user) |
The config file holds a credential
config.toml contains the agent token, and — if you enable SSH — the SSH host
private key. It is written 0600. Treat it as a secret if you copy it anywhere.
Verify what you installed
Every release asset ships a SHA-256 sidecar, a detached GPG signature
(.asc, against a published release key) and SLSA build provenance:
gh attestation verify roomlerd-<version>-x86_64-unknown-linux-gnu.deb \
--repo gjovanov/roomler-aiThe agent’s own updater verifies the GPG signature against a key pinned inside the binary before it will install anything, and refuses if the signature is absent or does not match.
Keeping it updated
The agent self-updates on a timer, verifying the signature before handing off to
dpkg. Admins can also push a specific version per device or fleet-wide.
`dpkg -i` alone does not restart the daemon
Installing a package by hand replaces the file on disk while the running process
keeps executing the deleted inode — so roomler --version reports the new
version while the daemon is still the old one. Restart the unit explicitly after
a manual install.
Uninstall
One command removes everything Roomler put on the machine, however it got
there: the daemon, the desktop companion and the tunnel CLI, from the .deb,
the .rpm, the tarball or the install script.
curl -fsSL https://roomler.ai/api/setup/install.sh | sh -s -- --uninstallIt stops each service through systemd before removing anything: the system
roomlerd.service, the per-user roomler.service and the update helper
(roomler-update.timer and .path). That stop is the daemon’s clean stop, so
the routes and DNS settings it added to the machine go with it. Then the
packages and files, then the config. It prints done. only if every step
worked; otherwise it lists what it could not remove and exits non-zero.
| Flag | Effect |
|---|---|
--keep-config |
Keep /etc/roomler and ~/.config/roomler: a reinstall comes back as the same device |
Then remove the device in the dashboard under Devices. That revokes its credential and releases its mesh address. A device cannot do this for itself, except an ephemeral one, which removes itself when its daemon stops.
Other accounts on the machine
The config that is removed is that of the account running the command (the one
behind sudo), plus root’s. If another account on the machine enrolled its own
per-user install, its config stays, and the command lists where it is.
Troubleshooting
- The device never appears. The token is single-use; mint a fresh one.
- Installed but shows offline. Check the unit is actually enabled and that the machine has outbound HTTPS. See device offline or stale.
- Screen is black on a desktop. The per-user unit needs a logged-in session; a root system service does not have one. See black screen.
- More → Troubleshooting.