Skip to main content
Platforms

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

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.

Next steps