Skip to main content
Deploy Nodes

Rivet Services

Self-host Durable Streams and agentOS VMs.

Rivet Services is a prebuilt node that hosts Rivet’s own Actors. Run it next to your control plane when you self-host. On Rivet Cloud it is already running.

Services included

Durable Streams

Real-time streams with durable history, served over HTTP at http://<host>:8642/durable-streams/v1/stream/<path>. See Durable Streams.

agentOS

Hosted agentOS VMs, created and called through your control plane. See agentOS.

Run it

You need a running control plane and its Rivet token. See Control Plane to set one up.

Create the services node pool

curl -X PUT "http://localhost:6420/pools/services?namespace=default" \
  -H "Authorization: Bearer $RIVET_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{}'

Start Services

Docker run

docker run -d --name rivet-services \
  --add-host=host.docker.internal:host-gateway \
  -e RIVET_ENDPOINT=http://host.docker.internal:6420 \
  -e RIVET_TOKEN="$RIVET_TOKEN" \
  -e HOST=0.0.0.0 \
  -p 8642:8642 \
  rivetdev/services:0.2.5

Docker Compose

Add this service next to rivet in the Compose file from the Docker Compose guide:

  rivet-services:
    image: rivetdev/services:0.2.5
    ports:
      - "8642:8642"
    environment:
      RIVET_ENDPOINT: "http://rivet:6420"
      RIVET_TOKEN: "${RIVET_TOKEN}"
      HOST: "0.0.0.0"
    depends_on:
      - rivet
    restart: unless-stopped

Check that it works

Durable Streams

curl -X PUT -H 'content-type: application/json' \
  --data '[{"message":"hello"}]' \
  http://localhost:8642/durable-streams/v1/stream/demo

curl 'http://localhost:8642/durable-streams/v1/stream/demo?offset=-1'

The read returns [{"message":"hello"}].

agentOS

Create a VM in the services pool, then run a command in it:

VM_ID=$(curl -s -X PUT "http://localhost:6420/actors?namespace=default" \
  -H "Authorization: Bearer $RIVET_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"name":"agentOS","key":"my-vm","pool":"services","crash_policy":"sleep"}' \
  | jq -r .actor.actor_id)

curl "http://localhost:6420/gateway/$VM_ID/action/v1.process.run" \
  -H "x-rivet-token: $RIVET_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"args":[{"command":"sh","args":["-c","echo hello"],"options":{"captureStdio":true}}]}'

The response includes "stdout":"hello\n".

Configuration

VariableDescription
RIVET_ENDPOINTWhere Services reaches the control plane.
RIVET_TOKENYour Rivet token.
RIVET_NAMESPACEThe namespace to join. Defaults to default.
HOSTAddress to listen on. Set 0.0.0.0 in a container.
PORTPort to listen on. Defaults to 8642.

Local development

rivetkit dev starts Services for you. Without RivetKit, npx @rivet-dev/services dev starts a local control plane and Services together.