# Docker Compose

> Source: `src/content/docs/self-hosting/docker-compose.mdx`
> Canonical URL: https://rivet.dev/docs/self-hosting/docker-compose
> Description: Deploy Rivet Engine with docker-compose for multi-container setups.

---
## Quick Start

### Create docker-compose.yaml

Create a `docker-compose.yaml` in your project root:

```yaml
services:
  rivet-engine:
    image: rivetdev/engine:latest
    ports:
      - "6420:6420"
    volumes:
      - rivet-data:/data
    environment:
      RIVET__FILE_SYSTEM__PATH: "/data"
    restart: unless-stopped

volumes:
  rivet-data:
```

### Start the engine

```bash
docker-compose up -d
```

## Connecting Your Project

Once the engine is running, add your app as a service in the same Compose file.

### Create your server

Follow the [quickstart](/docs/actors/quickstart/backend) to create a working server with actors.

### Create a Dockerfile

Create a `Dockerfile` in your project root:

```dockerfile @nocheck
FROM node:22-slim
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN corepack enable && pnpm install --frozen-lockfile
COPY . .
RUN pnpm build
CMD ["node", "dist/index.js"]
```

### Add your app to docker-compose.yaml

Update your `docker-compose.yaml` to include your app alongside the engine:

```yaml
services:
  rivet-engine:
    image: rivetdev/engine:latest
    ports:
      - "6420:6420"
    volumes:
      - rivet-data:/data
    environment:
      RIVET__FILE_SYSTEM__PATH: "/data"
    restart: unless-stopped

  my-app:
    build: .
    environment:
      RIVET_ENDPOINT: "http://default:admin@rivet-engine:6420"
    depends_on:
      - rivet-engine
    restart: unless-stopped

volumes:
  rivet-data:
```

`RIVET_ENDPOINT` tells your app to connect to the engine as a runner instead of running standalone. The URL uses the format `http://namespace:token@host:port`. Inside the Docker network, your app reaches the engine at `rivet-engine:6420`. See [Endpoints](/docs/general/endpoints) for all options.

### Start the services

```bash
docker-compose up -d
```

### Register your runner with the engine

### Dashboard

1. Open the Rivet Engine dashboard at `http://localhost:6420`.
2. Enter your admin token when prompted.
3. In the namespace sidebar, click **Settings**.
4. Click **Add Provider**, then choose **Custom**.
5. Click **Next** (these settings can be changed later).
6. Click **Next** (you can safely skip the env ar step for Docker Compose).
5. Go to **Confirm Connection**, enter your app endpoint (`http://my-app:6420/api/rivet`), then click **Add**.

### CLI (curl)

Register your runner programmatically via the engine API:

```bash @nocheck
curl -X PUT "http://localhost:6420/runner-configs/default?namespace=default" \
  -H "Content-Type: application/json" \
  -d '{
    "datacenters": {
      "default": {
        "normal": {}
      }
    }
  }'
```

## Configuration

### Config File

Mount a JSON configuration file in your `docker-compose.yaml`:

```yaml
services:
  rivet-engine:
    image: rivetdev/engine:latest
    ports:
      - "6420:6420"
    volumes:
      - ./rivet-config.json:/etc/rivet/config.json:ro
      - rivet-data:/data
    restart: unless-stopped

volumes:
  rivet-data:
```

Create `rivet-config.json` in the same directory as your `docker-compose.yaml`. See the [Configuration](/docs/self-hosting/configuration) docs for all available options and the full [JSON Schema](/docs/engine-config-schema.json).

```json
{
  "postgres": {
    "url": "postgresql://rivet:password@postgres:5432/rivet"
  }
}
```

### Postgres Setup

PostgreSQL is the recommended backend for multi-node self-hosted deployments today, but it remains experimental. For a production-ready single-node Rivet deployment, use the file system backend (RocksDB-based). Enterprise teams can contact [enterprise support](https://rivet.dev/sales) about FoundationDB for the most scalable production-ready deployment.

```yaml
services:
  postgres:
    image: postgres:15
    environment:
      POSTGRES_DB: rivet
      POSTGRES_USER: rivet
      POSTGRES_PASSWORD: rivet_password
    volumes:
      - postgres-data:/var/lib/postgresql/data
    restart: unless-stopped

  rivet-engine:
    image: rivetdev/engine:latest
    ports:
      - "6420:6420"
    environment:
      RIVET__POSTGRES__URL: postgresql://rivet:rivet_password@postgres:5432/rivet
    depends_on:
      - postgres
    restart: unless-stopped

volumes:
  postgres-data:
```

## Next Steps

- Review the [Production Checklist](/docs/self-hosting/production-checklist) before going live
- See [Configuration](/docs/self-hosting/configuration) for all options

_Source doc path: /docs/self-hosting/docker-compose_
