Rivet Services
Self-host Durable Streams and agentOS VMs.
Rivet Services is a container of prebuilt Rivet Actors that provide services such as Durable Streams and agentOS VMs.
Run it alongside your control plane when you self-host these services. 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>. Each stream is its own Rivet Actor, which stores the stream’s history and metadata. 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
| Variable | Description |
|---|---|
RIVET_ENDPOINT | Where Services reaches the control plane. |
RIVET_TOKEN | Your Rivet token. |
RIVET_NAMESPACE | The namespace to join. Defaults to default. |
HOST | Address to listen on. Set 0.0.0.0 in a container. |
PORT | Port to listen on. Defaults to 8642. |
Local development
RivetKit starts Services automatically during local development when you run your application with its managed local control plane. Without RivetKit, npx @rivet-dev/services dev starts a local control plane and Services together.
Persistence and where data is stored
Services provides prebuilt Rivet Actors that use each Actor’s durable SQLite storage. This data is persisted by the control plane, not in the Services container. You don’t need to configure any storage for Services.