Docker Compose
Run Rivet workers with Docker Compose.
Workers run in runner mode here: the container opens a connection out to the control plane on startup. It needs no published port.
Requirements
- Docker with the Compose plugin
- A control plane, either Rivet Cloud or your own
Steps
Package your app
FROM node:24-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
CMD ["node", "server.js"]
CMD invokes the binary directly rather than npm start, so the process receives SIGTERM and can drain.
Rivet requires Node 22 or newer. Alpine images need a build toolchain because Rivet’s SQLite dependency has no musl prebuilt binary, so the Debian-based image is the smaller working choice.
Add the service
stop_grace_period matters here. Actors drain for up to 30 minutes, and Compose’s default of 10 seconds cuts them off.
services:
my-app:
build: .
environment:
RIVET_ENDPOINT: "${RIVET_ENDPOINT}"
RIVET_PUBLIC_ENDPOINT: "${RIVET_PUBLIC_ENDPOINT}"
stop_grace_period: 35m
restart: unless-stopped
Both endpoint values are described in Workers. Put them in a .env file next to the Compose file and keep it out of version control.
Run alongside a self-hosted control plane
When both halves live in the same Compose file, the worker reaches the control plane by service name over the Compose network:
my-app:
build: .
environment:
RIVET_ENDPOINT: "http://default:${RIVET_ADMIN_TOKEN}@rivet-engine:6420"
depends_on:
- rivet-engine
stop_grace_period: 35m
restart: unless-stopped
See the control plane guide for the other half of this file.
Create the runner config
A worker is refused until a runner config exists for its pool. Against a self-hosted control plane, create it once:
curl -X PUT "http://localhost:6420/runner-configs/default?namespace=default" \
-H "Authorization: Bearer $RIVET_ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"datacenters":{"default":{"normal":{}}}}'
Rivet Cloud does this for you. See Runner configs.
Start it
docker compose up -d
Verify
docker compose ps
The service should be running. It then appears under Runners in the dashboard.
Scaling
Compose has no autoscaler. Runner-mode workers are interchangeable, so docker compose up -d --scale my-app=3 adds replicas that all join the same pool, but they share one host’s CPU and memory. For capacity beyond a single host, or for autoscaling, move to Kubernetes or ECS.
Keep stop_grace_period: 35m on every replica. Scaling down cuts actors off otherwise.