// install · agent node
Install an agent node
An agent node runs the RivetOS runtime and enrolls against your datahub over SSH. You need a working datahub first.
Requirements
- Debian 12 or Ubuntu LTS, x86_64 or aarch64, with systemd.
- Root (
sudo) and about 512 MiB free disk (2 GiB comfortable fornpm ci). - An SSH login on the datahub that can run
rivethub-hub— this is your--hubtarget. - The installer runs as root, so BatchMode SSH uses
/root/.ssh— copy your key there (orssh-copy-idas root) before a curl-pipe orsudorun. curl,python3,tar,ssh,flock, andgit(bare-metal) — missing ones are installed viaapt-getwhen run as root.dockerin PATH only if you choose--docker.
// the command
Curl-pipe is supported
$ curl -fsSL https://get.rivethub.io/node.sh | bash -s -- --hub owner@192.0.2.10
Or from a checkout of the rivethub-distro repository:
$ sudo bash install/node.sh [--docker] [--hub owner@192.0.2.10] [--name node-a] [--advertise-host 192.0.2.11]
Re-running is safe. Re-run without --hub and the
installer resumes HUB_TARGET / NODE_NAME from
$RIVETHUB_ROOT/node.env.
// the prompts
What the installer asks
On a TTY, unset fields are prompted:
- Datahub SSH target — the
user@hostfor--hub. Required when stdin is not a TTY and nonode.envhas one recorded. - Mesh node name — the certificate CN
(
[a-z0-9-], max 63). Default: the hostname, sanitized. - Advertise host — the address other nodes use to
reach this node. Default:
hostname -f.
Enrollment happens over SSH: the installer runs
rivethub-hub enroll <node-name> <advertise-host>
on the datahub, and stdout is only a base64 tarball (leaf cert + key,
ca-chain.pem, current mesh.json, node config
snippet), unpacked into the local shared dir.
rivetos mesh enroll is not merged upstream yet — the
installer implements the same tarball contract today.
// layout
What gets installed where
/opt/rivetos- RivetOS checkout at the
pins/stable.jsonrivetos_tag(bare-metal; Node 22+ from NodeSource) /var/lib/rivethub/shared- local
mesh.json+rivet-ca(RIVETOS_SHARED_DIR) /rivet-shared- symlink to the shared dir, so hardcoded RivetOS TLS paths work
/home/rivet/.rivetosconfig.yaml+.env(mode 0600) for therivetuser (uid 2000 if free)/var/lib/rivethub/node.env- recorded identity (node name, hub target) — no secrets
/etc/systemd/system/rivetos-agent.service- the agent unit (enabled + started)
Bare-metal (systemd) is the default. --docker runs the
pinned GHCR image under systemd with host networking on mesh port
3000.
pins/stable.json is UNPINNED: the clone falls
back to the default branch with a loud warning, and
--docker falls back to a floating GHCR tag, until the
first stable tag is pinned. See
Releases.
// verify
Verify
$ systemctl status rivetos-agent
$ journalctl -u rivetos-agent -n 50
$ sudo -u rivet -H rivetos status
$ sudo -u rivet -H rivetos doctor
The mesh certificate lives at
/var/lib/rivethub/shared/rivet-ca/issued/<node-name>.crt.
// next
Add the next node
Run the same command on another host, with a fresh name and address:
$ curl -fsSL https://get.rivethub.io/node.sh | bash -s -- --hub owner@192.0.2.10 --name node-b --advertise-host 192.0.2.11
Renew certificates
Renewal is driven from the datahub, which re-issues the node's leaf and emits the same tarball:
$ rivethub-hub renew <node-name>
To change a node's address, re-enroll it instead of renewing.