Skip to main content
Platforms

Docker Compose

Run the Rivet control plane with Docker Compose.

Requirements

  • Docker with the Compose plugin
  • A host with a persistent volume

Steps

Create docker-compose.yaml

This is a single-node deployment on the file system backend. The named volume is what makes the data survive a restart.

services:
  rivet-engine:
    image: rivetdev/engine:latest
    ports:
      - "6420:6420"
    volumes:
      - rivet-data:/data
    environment:
      RIVET__FILE_SYSTEM__PATH: "/data"
      RIVET__AUTH__ADMIN_TOKEN: "${RIVET_ADMIN_TOKEN}"
    restart: unless-stopped

volumes:
  rivet-data:

Generate an admin token

echo "RIVET_ADMIN_TOKEN=$(openssl rand -hex 32)" >> .env

Without a token the API is unauthenticated. Keep .env out of version control.

Start it

docker compose up -d

Verify

curl -i http://localhost:6420/health

Expect 200. The dashboard is at http://localhost:6420/ui; log in with the admin token.

Create the runner config

A runner config declares a pool that workers connect to. Without one the control plane refuses every worker, so create it before adding your app:

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":{}}}}'

Use normal for the long-lived workers this file runs. See Runner configs.

Add a worker

Add your app to the same Compose file. Inside the Compose network it reaches the control plane at rivet-engine:6420.

  my-app:
    build: .
    environment:
      RIVET_ENDPOINT: "http://default:${RIVET_ADMIN_TOKEN}@rivet-engine:6420"
    depends_on:
      - rivet-engine
    restart: unless-stopped
docker compose up -d

Confirm the worker appears under Runners in the dashboard.

Using PostgreSQL

Swap the file system backend for PostgreSQL when you outgrow one node.

services:
  postgres:
    image: postgres:15
    environment:
      POSTGRES_DB: rivet
      POSTGRES_USER: rivet
      POSTGRES_PASSWORD: rivet_password
    volumes:
      - postgres-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U rivet -d rivet"]
      interval: 5s
      timeout: 5s
      retries: 12
    restart: unless-stopped

  rivet-engine:
    image: rivetdev/engine:latest
    ports:
      - "6420:6420"
    environment:
      RIVET__POSTGRES__URL: postgresql://rivet:rivet_password@postgres:5432/rivet
      RIVET__AUTH__ADMIN_TOKEN: "${RIVET_ADMIN_TOKEN}"
    depends_on:
      postgres:
        condition: service_healthy
    restart: unless-stopped

volumes:
  postgres-data:

This file still runs a single engine container, so it is not yet a multi-node deployment. It is the prerequisite for one: the file system backend is single-node RocksDB and cannot be shared, while PostgreSQL can. Multi-node deployments also need NATS. See Storage.

Using a config file

Mount JSON instead of setting environment variables:

    volumes:
      - ./rivet-config.json:/etc/rivet/config.json:ro
      - rivet-data:/data

See Configuration for the full schema.

Next steps