Skip to main content
Platforms

Kubernetes

Deploy production-ready Rivet Engine to Kubernetes with PostgreSQL storage.

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 about FoundationDB for the most scalable production-ready deployment.

Prerequisites

  • Kubernetes cluster
  • kubectl configured
  • Metrics server (required for HPA) — included by default in most distributions (k3d, GKE, EKS, AKS)

Deploy Rivet Engine

Download Manifests

Download the self-host/k8s/engine directory from the Rivet repository:

npx giget@latest gh:rivet-dev/rivet/self-host/k8s/engine rivet-k8s
cd rivet-k8s

Configure Engine

In 02-engine-configmap.yaml, set public_url to your engine’s external URL.

Configure PostgreSQL

In 11-postgres-secret.yaml, update the PostgreSQL password. See Using a Managed PostgreSQL Service for external databases.

Configure Admin Token

Generate a secure admin token and save it somewhere safe:

openssl rand -hex 32

Create the namespace and store the token as a Kubernetes secret:

kubectl create namespace rivet-engine
kubectl -n rivet-engine create secret generic rivet-secrets --from-literal=admin-token=YOUR_TOKEN_HERE

Deploy

# Apply all manifests
kubectl apply -f .

# Wait for all pods to be ready
kubectl -n rivet-engine wait --for=condition=ready pod -l app=nats --timeout=300s
kubectl -n rivet-engine wait --for=condition=ready pod -l app=postgres --timeout=300s
kubectl -n rivet-engine wait --for=condition=ready pod -l app=rivet-engine --timeout=300s

# Verify all pods are running
kubectl -n rivet-engine get pods

Access the Engine

Visit /ui on your public_url to access the dashboard.

Connecting Your Project

Create your server

Follow the quickstart to create a working server with actors.

Create Kubernetes manifests

Create these manifest files for your app:

Configure the endpoint

Create rivetkit-secrets.yaml with RIVET_ENDPOINT pointing to the engine. This tells your app to connect as a runner instead of running standalone. See Endpoints for all options.

apiVersion: v1
kind: Secret
metadata:
  name: rivetkit-secrets
  namespace: your-namespace
type: Opaque
stringData:
  RIVET_ENDPOINT: http://my-app:your-admin-token@your-engine.example.com

Deploy your app

kubectl apply -f rivetkit-secrets.yaml
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml

Register your runner with the engine

Advanced

Using a Managed PostgreSQL Service

If you prefer to use a managed PostgreSQL service (e.g. Amazon RDS, Cloud SQL, Azure Database) instead of the bundled Postgres deployment:

  • Update the postgres.url connection string in 02-engine-configmap.yaml to point to your managed instance
  • Delete the bundled PostgreSQL manifests:
    • 10-postgres-configmap.yaml
    • 11-postgres-secret.yaml
    • 12-postgres-statefulset.yaml
    • 13-postgres-service.yaml

Applying Configuration Updates

When making subsequent changes to 02-engine-configmap.yaml, restart the engine pods to pick up the new configuration:

kubectl apply -f 02-engine-configmap.yaml
kubectl -n rivet-engine rollout restart deployment/rivet-engine

Ingress and Load Balancer Timeouts

Rivet uses long-lived WebSocket connections for both client traffic (browsers, SDKs) and envoy traffic (actor hosts connecting back to the engine). Default Ingress and cloud load balancer idle timeouts (typically 30 to 60 seconds) drop these connections and cause reconnect storms.

Raise the idle / read / send timeout on every Ingress and load balancer in front of the engine to at least 1 hour (3600 seconds). Examples:

  • NGINX Ingress (annotations on the Ingress):

    nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
    
  • AWS Load Balancer Controller (ALB):

    alb.ingress.kubernetes.io/load-balancer-attributes: idle_timeout.timeout_seconds=3600
    
  • GCE Ingress (GKE): set timeoutSec: 3600 on the BackendConfig referenced by the Service.

The same guidance applies to the load balancer fronting your RivetKit app, since envoys connect to it over WebSocket.

Next Steps