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 | sudo bash -s -- --hub owner@192.0.2.10
Or from the distro/ directory of a RivetOS checkout:
$ sudo bash install/node.sh --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, then a SUMMARY, then an
explicit yes. --yes skips the confirm; on
non-TTY it also accepts documented defaults (name = hostname,
advertise-host = hostname -f). --hub has no
default — missing answers are listed together with their env names
(RIVETHUB_HUB).
- 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. On an existing RivetOS
install, rivetos mesh enroll drives the same contract
from the CLI.
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. Check Releases for the distinction between installer pins, runtime releases, and desktop downloads.
verify
Verify
$ systemctl status rivetos-agent.service
$ journalctl -u rivetos-agent.service -n 50
$ sudo -u rivet -H rivetos status
$ sudo -u rivet -H rivetos doctor
The systemd unit is rivetos-agent.service (not
rivetos.service). The mesh certificate lives at
/var/lib/rivethub/shared/rivet-ca/issued/<node-name>.crt.
Day-2 mesh sync / renew run as the rivet user (the
installer generated /home/rivet/.ssh/id_ed25519 and
installed the pubkey on --hub via the root hop):
$ sudo -u rivet -H rivetos mesh sync
$ sudo -u rivet -H rivetos mesh renew
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 | sudo 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:
rivethub-hub renew <node-name> re-issues the node’s
leaf certificate and emits the same tarball as enrollment. To change a
node’s address, re-enroll it instead of renewing.