Operations

Deployment

Deploy the Realtime Platform to production with Docker, process managers, or cloud services.

This guide covers deploying the Realtime Platform to production environments.

Build for Production

pnpm build

Turborepo builds all packages in dependency order. The output is:

AppOutputType
Backendapps/backend/dist/Node.js server
Workersapps/workers/dist/Node.js processes
Admin UIapps/admin-ui/dist/Static files

Running in Production

Backend API

NODE_ENV=production pnpm --filter @realtime/backend start

The backend starts the Express HTTP server with Socket.IO on the configured PORT (default 3000). Migrations run automatically on startup.

Workers

NODE_ENV=production pnpm --filter @realtime/workers start

Workers run as a long-lived Node.js process. They connect to Redis (BullMQ) and optionally to the CDC target database.

Admin UI

The Admin UI builds to static files in apps/admin-ui/dist/. Serve with any static file server:

server {
  listen 80;
  root /path/to/apps/admin-ui/dist;
  index index.html;

  location / {
    try_files $uri $uri/ /index.html;
  }
}

Set VITE_API_URL at build time to point to your production backend:

VITE_API_URL=https://api.yourplatform.com pnpm --filter @realtime/admin-ui build

Docker Deployment

Example Dockerfile (Backend)

FROM node:20-alpine AS builder
WORKDIR /app
COPY . .
RUN npm install -g pnpm@9
RUN pnpm install --frozen-lockfile
RUN pnpm build

FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app .
ENV NODE_ENV=production
EXPOSE 3000
CMD ["node", "apps/backend/dist/index.js"]

Example Dockerfile (Workers)

FROM node:20-alpine AS builder
WORKDIR /app
COPY . .
RUN npm install -g pnpm@9
RUN pnpm install --frozen-lockfile
RUN pnpm build

FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app .
ENV NODE_ENV=production
CMD ["node", "apps/workers/dist/index.js"]

Infrastructure Requirements

ServiceProduction Recommendation
PostgreSQLManaged service (RDS, Cloud SQL) with connection pooling
RedisManaged service (ElastiCache, Redis Cloud) with RedisJSON
Backend2+ instances behind a load balancer
Workers1+ instances (stateless, horizontally scalable)

Environment Variables

Ensure all required environment variables are set in production:

NODE_ENV=production
PORT=3000
LOG_LEVEL=info

DATABASE_URL=postgresql://user:pass@db-host:5432/realtime
REDIS_URL=redis://user:pass@redis-host:6379

CDC_DATABASE_URL=postgresql://user:pass@app-db:5432/yourapp

Warning

Never use default passwords or JWT_SECRET in production. Use the signing key management system with key rotation.

Health Checks

Configure your load balancer or orchestrator to use the health endpoint:

GET /health
# Returns {"status":"ok"} with 200

Horizontal Scaling

The platform is designed for horizontal scaling:

  • Backend instances share state through Redis and PostgreSQL — add more behind a load balancer
  • Workers are stateless and process jobs from BullMQ — add more to increase throughput
  • Socket.IO uses Redis Pub/Sub adapter for cross-instance message delivery
  • Sticky sessions are NOT required — Socket.IO handles reconnection across instances

SSL/TLS

In production, terminate TLS at the load balancer or reverse proxy. Configure Redis and PostgreSQL connections with TLS:

REDIS_URL=rediss://user:pass@redis-host:6379
DATABASE_URL=postgresql://user:pass@db-host:5432/realtime?sslmode=require