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 buildTurborepo builds all packages in dependency order. The output is:
| App | Output | Type |
|---|---|---|
| Backend | apps/backend/dist/ | Node.js server |
| Workers | apps/workers/dist/ | Node.js processes |
| Admin UI | apps/admin-ui/dist/ | Static files |
Running in Production
Backend API
NODE_ENV=production pnpm --filter @realtime/backend startThe 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 startWorkers 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 buildDocker 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
| Service | Production Recommendation |
|---|---|
| PostgreSQL | Managed service (RDS, Cloud SQL) with connection pooling |
| Redis | Managed service (ElastiCache, Redis Cloud) with RedisJSON |
| Backend | 2+ instances behind a load balancer |
| Workers | 1+ 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/yourappWarning
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 200Horizontal 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