Deployment
RivetOS supports three deployment targets: Docker (recommended for most users), Proxmox (homelab), and bare-metal (manual). This guide covers each approach, multi-agent setups, networking, and backup/restore.
The unified Compose stack lives at
infra/docker/rivetos/docker-compose.yml. Throughout this guide,docker compose ...examples assume you’ve either passed-f infra/docker/rivetos/docker-compose.ymlor exportedCOMPOSE_FILE=infra/docker/rivetos/docker-compose.ymlfrom the repo root.
Docker Deployment
The simplest way to run RivetOS. Works on any machine with Docker.
Single Agent
# Clone and install (automatically builds all packages)
git clone https://github.com/philbert440/rivetOS.git
cd rivetOS
npm install
# Run the interactive setup
npx rivetos init
# Choose "Docker" as deployment target
# Configure your agent, API key, and channels
# The wizard generates config.yaml + .env + starts containers
# Or manually:
cp config.example.yaml config.yaml
cp .env.example .env
# Edit both files, then:
npx rivetos build
docker compose -f infra/docker/rivetos/docker-compose.yml up -d
Multi-Agent
The unified Compose stack ships a single agent service. Multi-agent fleets are deployed as separate hosts/CTs joined into a mesh — see Mesh Networking — rather than as N agent services in one Compose file. The CLI’s rivetos agent add and rivetos init --join walk you through this.
Docker Compose Architecture
The unified stack runs four services off two images: upstream pgvector/pgvector:pg16 for the database and a single role-dispatched runtime image (rivetos). Schema is applied by the migrate role at stack startup — there is no custom datahub image to build or push.
┌─────────────────────────────────────────────┐
│ Docker Network: rivetos-net │
│ │
│ ┌─────────┐ ┌──────────┐ ┌────────────┐ │
│ │ migrate │ │ workers │ │ agent │ │
│ │ (rivetos│ │ (rivetos │ │ (rivetos │ │
│ │ one- │ │ --role │ │ --role │ │
│ │ shot) │ │ worker) │ │ agent) │ │
│ └────┬────┘ └────┬─────┘ └────┬───────┘ │
│ │ │ │ │
│ └────────────┼─────────────┘ │
│ │ │
│ ┌───────┴────────┐ │
│ │ datahub │ │
│ │ postgres:16 │ │
│ │ + pgvector │ │
│ │ :5432 │ │
│ └────────────────┘ │
└─────────────────────────────────────────────┘
Volumes:
rivetos-pgdata → Postgres data (survives rebuilds)
~/.rivetos/config.yaml → Configuration (bind mount, read-only)
~/.rivetos/.env → Secrets (bind mount, read-only)
Data Persistence
Containers are stateless. All persistent data lives on the host:
| Data | Storage | Survives Update |
|---|---|---|
| Configuration | Bind mount ~/.rivetos/config.yaml |
✅ |
| Secrets | Bind mount ~/.rivetos/.env |
✅ |
| PostgreSQL data | Named volume rivetos-pgdata |
✅ |
| Plugins | In source tree | ✅ |
| Runtime code | Rebuilt from source | 🔄 |
Updating
npx rivetos update
This pulls the latest source, rebuilds container images, and restarts. Your workspace, config, secrets, and database survive.
For a specific version:
npx rivetos update --version 0.8.2
Proxmox Deployment
For homelab setups with Proxmox VE. Each agent runs in its own LXC container.
Prerequisites
- Proxmox VE 8.x
- At least one node with sufficient RAM (1-2 GB per agent container)
- Network bridge configured (e.g.,
vmbr1)
Configuration
# config.yaml
deployment:
target: proxmox
datahub:
postgres: true
shared_storage: true
image:
build_from_source: true
proxmox:
api_url: https://192.168.1.1:8006
nodes:
- name: pve1
host: 192.168.1.1
role: datahub # Runs Postgres + NFS
- name: pve2
host: 192.168.1.2
role: agents # Runs agent containers
- name: pve3
host: 192.168.1.3
role: agents
network:
bridge: vmbr1
subnet: 192.168.1.0/24
gateway: 192.168.1.1
Deployment
Use the provisioning scripts under infra/scripts/ and the Compose files under
infra/docker/ to stand up containers on each node. There is no
unified rivetos infra command — provisioning is intentionally script-driven so
you keep full control over Proxmox/Docker semantics.
Proxmox Architecture
┌────────────────────────────────────────────────────────┐
│ Network: 192.168.1.0/24 (vmbr1) │
│ │
│ PVE1 (datahub) PVE2 (agents) PVE3 (agents) │
│ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │
│ │ CT 106 │ │ CT 101 │ │ CT 100 │ │
│ │ postgres │ │ opus │ │ local │ │
│ │ NFS server │ │ 192.168.1.101 │ │ 192.168.1.100 │ │
│ │ /rivet-shared/ │ ├───────────────┤ └───────────────┘ │
│ │ 192.168.1.106 │ │ CT 102 │ │
│ └───────────────┘ │ grok │ │
│ │ 192.168.1.102 │ │
│ └───────────────┘ │
│ │
│ NFS exports /rivet-shared/ to all agents │
│ Agents mount /rivet-shared/ via bind mount │
└────────────────────────────────────────────────────────┘
Multi-Node Shared Storage
The datahub node runs NFS to share /rivet-shared/ across all agents:
# On the datahub node:
apt install nfs-kernel-server
echo "/rivet-shared 192.168.1.0/24(rw,sync,no_subtree_check)" >> /etc/exports
exportfs -ra
# On each Proxmox host:
mount -t nfs 192.168.1.106:/rivet-shared /rivet-shared
# Add to fstab for persistence
echo "192.168.1.106:/rivet-shared /rivet-shared nfs defaults 0 0" >> /etc/fstab
Each agent container gets /rivet-shared/ as a bind mount.
Updating on Proxmox
# Update all agents (rolling — one at a time with health checks)
npx rivetos update --mesh
# Update a single agent
npx rivetos update
Multi-Agent Mesh
Multiple RivetOS instances can form a mesh for cross-instance collaboration.
Setting Up a Mesh
First instance (seed node):
npx rivetos init
# Configure normally — this becomes the seed
Additional instances:
npx rivetos init --join 192.168.1.101
# Discovers the existing mesh and registers
Mesh Operations
# List all mesh nodes
npx rivetos mesh list
# Health check all peers
npx rivetos mesh ping
# Show local mesh status
npx rivetos mesh status
# Join an existing mesh
npx rivetos mesh join 192.168.1.101
How Mesh Delegation Works
When an agent receives a delegate_task targeting an agent that isn’t local:
- Check local agents → not found
- Check mesh registry → found on remote node
- Send delegation request via HTTP to the remote agent channel
- Remote agent processes the task
- Result returned to the requesting agent
This is transparent — the requesting agent doesn’t know or care whether the delegate is local or remote.
Mesh Configuration
# Agent channel config (enables mesh)
channels:
agent:
port: 3100
secret: ${RIVETOS_AGENT_SECRET}
# Mesh seeds (optional — for discovery)
# Peers are also discovered via rivetos init --join
Bare-Metal Deployment
Run RivetOS directly on your machine without containers.
Setup
git clone https://github.com/philbert440/rivetOS.git
cd rivetOS
npm install # Installs deps + builds all packages
# Configure
cp config.example.yaml config.yaml
cp .env.example .env
# Edit both files
# Start
npx rivetos start
Systemd Service
# Generate the systemd unit (a per-user unit unless you run it as root)
npx rivetos service init
# Manage it through the CLI — it wraps systemctl and picks --user vs system automatically
npx rivetos service start
npx rivetos service stop
npx rivetos service restart
npx rivetos service status
npx rivetos service logs # follow the journal
# Enable on boot (user unit; drop --user if you ran `service init` as root)
systemctl --user enable rivetos
# Uninstall: stop, disable, then delete the unit file (path is printed by `service init`)
npx rivetos service stop
systemctl --user disable rivetos
PostgreSQL Setup
You need PostgreSQL 16+ with pgvector running separately:
# Ubuntu/Debian
sudo apt install postgresql-16 postgresql-16-pgvector
sudo -u postgres createdb rivetos
sudo -u postgres psql rivetos -c "CREATE EXTENSION IF NOT EXISTS vector;"
# Set connection string
echo 'RIVETOS_PG_URL=postgresql://localhost:5432/rivetos' >> .env
Networking
Port Reference
| Port | Service | Description |
|---|---|---|
| 3100 | Agent HTTP | Agent channel (delegation, mesh, health) |
| 5432 | PostgreSQL | Database (datahub only) |
Firewall Rules
For multi-instance setups, agents need to reach each other on port 3100 and the datahub on port 5432:
# Allow agent mesh traffic (adjust subnet)
ufw allow from 192.168.1.0/24 to any port 3100
ufw allow from 192.168.1.0/24 to any port 5432
DNS / Service Discovery
The mesh uses seed-node discovery by default. When you rivetos init --join <host>, the joining node contacts the seed’s /api/mesh/join endpoint and receives the full registry of known peers.
mDNS auto-discovery is supported for future use but not yet implemented.
Backup & Restore
What to Back Up
| Component | Location | Method |
|---|---|---|
| Config | ./config.yaml |
File copy |
| Secrets | ./.env |
File copy (secure!) |
| Workspace | ./workspace/ |
File copy / rsync |
| Database | PostgreSQL | pg_dump |
| Shared storage | /rivet-shared/ or volume |
File copy / rsync |
Backup Script
#!/bin/bash
BACKUP_DIR="./backups/$(date +%Y%m%d-%H%M%S)"
mkdir -p "$BACKUP_DIR"
# Config and secrets
cp config.yaml "$BACKUP_DIR/"
cp .env "$BACKUP_DIR/"
# Workspace
rsync -a workspace/ "$BACKUP_DIR/workspace/"
# Database
docker compose -f infra/docker/rivetos/docker-compose.yml exec datahub pg_dump -U rivetos rivetos > "$BACKUP_DIR/database.sql"
# Shared storage
rsync -a /rivet-shared/ "$BACKUP_DIR/rivet-shared/"
echo "Backup complete: $BACKUP_DIR"
Restore
BACKUP_DIR="./backups/20260405-120000"
# Config and secrets
cp "$BACKUP_DIR/config.yaml" ./
cp "$BACKUP_DIR/.env" ./
# Workspace
rsync -a "$BACKUP_DIR/workspace/" workspace/
# Database
docker compose -f infra/docker/rivetos/docker-compose.yml exec -T datahub psql -U rivetos rivetos < "$BACKUP_DIR/database.sql"
# Shared storage
rsync -a "$BACKUP_DIR/rivet-shared/" /rivet-shared/
# Restart
npx rivetos update
Automated Backups
Set up a cron job:
# Daily at 3am
0 3 * * * /path/to/rivetos/backup.sh >> /var/log/rivetos-backup.log 2>&1
Resource Requirements
Minimum (Single Agent, Docker)
- CPU: 1 core
- RAM: 1 GB (512 MB for agent + 512 MB for Postgres)
- Disk: 2 GB (source + node_modules + database)
Recommended (Multi-Agent, Docker)
- CPU: 2+ cores
- RAM: 2-4 GB (512 MB per agent + 512 MB for Postgres)
- Disk: 10 GB (room for database growth and skills)
Proxmox (Per Container)
- Agent CT: 512 MB RAM, 1 vCPU, 2 GB disk
- Datahub CT: 1 GB RAM, 1 vCPU, 10 GB disk
Health Monitoring
Health Endpoint
Each agent exposes:
GET /health— Full runtime status (agents, providers, channels, memory, metrics)GET /health/live— Simple liveness check (returns 200)GET /metrics— Raw metrics (turns, tool calls, tokens, latency)
CLI Checks
npx rivetos status # Runtime overview
npx rivetos doctor # 12-category health check
npx rivetos test # Smoke test (provider, memory, tools)
npx rivetos mesh ping # Check all mesh peers
Docker Health Checks
The agent Dockerfile includes a built-in health check:
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
CMD wget -qO- http://localhost:3100/health/live || exit 1
Docker Compose uses this for dependency ordering — agents wait for the datahub to be healthy before starting.