Production Deployment
Deploy ChatSDK to production with proper environment configuration, scaling, and monitoring.
Environment Variables
Required (3 variables minimum)
# .env.production
DATABASE_URL=postgresql://user:pass@prod-db.com:5432/chatsdk
JWT_SECRET=your-cryptographically-secure-random-secret-min-32-chars
CENTRIFUGO_TOKEN_SECRET=another-cryptographically-secure-secret
Recommended
# Database
DATABASE_SSL=true
DATABASE_POOL_MIN=2
DATABASE_POOL_MAX=10
# Redis (caching & pub/sub)
REDIS_URL=redis://your-redis-cloud-url
# S3 Storage
S3_ENDPOINT=https://s3.amazonaws.com
S3_BUCKET=your-production-bucket
S3_ACCESS_KEY_ID=your-aws-key
S3_SECRET_ACCESS_KEY=your-aws-secret
# Meilisearch (full-text search)
MEILISEARCH_HOST=https://your-meilisearch-url
MEILISEARCH_API_KEY=your-api-key
# CORS
ALLOWED_ORIGINS=https://yourdomain.com,https://app.yourdomain.com
# Monitoring
SENTRY_DSN=https://your-sentry-dsn
DATADOG_API_KEY=your-datadog-key
Platform-Specific Guides
Vercel
# Install Vercel CLI
npm install -g vercel
# Deploy
vercel --prod
# Set environment variables
vercel env add DATABASE_URL production
vercel env add JWT_SECRET production
vercel env add CENTRIFUGO_TOKEN_SECRET production
vercel.json
{
"buildCommand": "npm run build",
"outputDirectory": ".next",
"regions": ["iad1"],
"env": {
"NODE_ENV": "production"
}
}
AWS Elastic Beanstalk
# Install EB CLI
pip install awsebcli
# Initialize
eb init -p node.js-18 chatsdk-app
# Create environment
eb create chatsdk-prod \
--database.engine postgres \
--database.size 10 \
--instance_type t3.medium
# Deploy
eb deploy
# Set environment variables
eb setenv \
JWT_SECRET=xxx \
CENTRIFUGO_TOKEN_SECRET=yyy \
NODE_ENV=production
Docker (Self-Hosted)
# Dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
EXPOSE 5500
CMD ["npm", "start"]
# Build
docker build -t chatsdk-app .
# Run
docker run -d \
-p 5500:5500 \
--env-file .env.production \
--name chatsdk \
chatsdk-app
Kubernetes
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: chatsdk
spec:
replicas: 3
selector:
matchLabels:
app: chatsdk
template:
metadata:
labels:
app: chatsdk
spec:
containers:
- name: chatsdk
image: your-registry/chatsdk:latest
ports:
- containerPort: 5500
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: chatsdk-secrets
key: database-url
- name: JWT_SECRET
valueFrom:
secretKeyRef:
name: chatsdk-secrets
key: jwt-secret
Database Setup
PostgreSQL
# Create production database
psql -U postgres -h your-db-host -p 5432
CREATE DATABASE chatsdk_production;
CREATE USER chatsdk_user WITH PASSWORD 'secure_password';
GRANT ALL PRIVILEGES ON DATABASE chatsdk_production TO chatsdk_user;
Managed Services
AWS RDS:
aws rds create-db-instance \
--db-instance-identifier chatsdk-prod \
--db-instance-class db.t3.medium \
--engine postgres \
--allocated-storage 100 \
--master-username chatsdk \
--master-user-password xxx
Google Cloud SQL:
gcloud sql instances create chatsdk-prod \
--database-version=POSTGRES_14 \
--tier=db-f1-micro \
--region=us-central1
Scaling Guidelines
Horizontal Scaling
# Scale API servers
kubectl scale deployment chatsdk --replicas=5
# Load balancer (Nginx)
upstream chatsdk_backend {
least_conn;
server api1.yourdomain.com;
server api2.yourdomain.com;
server api3.yourdomain.com;
}
server {
listen 443 ssl;
server_name api.yourdomain.com;
location / {
proxy_pass http://chatsdk_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
}
}
Database Scaling
-- Enable read replicas
-- Add connection pooling (PgBouncer)
-- Partition large tables
-- Example: Partition messages by month
CREATE TABLE messages (
id UUID PRIMARY KEY,
created_at TIMESTAMP NOT NULL,
...
) PARTITION BY RANGE (created_at);
CREATE TABLE messages_2024_01 PARTITION OF messages
FOR VALUES FROM ('2024-01-01') TO ('2024-02-01');
Monitoring
Health Checks
// app/api/health/route.ts
export async function GET() {
const checks = {
database: await checkDatabase(),
redis: await checkRedis(),
centrifugo: await checkCentrifugo(),
};
const isHealthy = Object.values(checks).every((c) => c.status === 'ok');
return Response.json(checks, {
status: isHealthy ? 200 : 503,
});
}
Logging
import winston from 'winston';
const logger = winston.createLogger({
level: 'info',
format: winston.format.json(),
transports: [
new winston.transports.File({ filename: 'error.log', level: 'error' }),
new winston.transports.File({ filename: 'combined.log' }),
],
});
logger.info('Message sent', { userId: 'user-123', messageId: 'msg-456' });
Error Tracking (Sentry)
import * as Sentry from '@sentry/nextjs';
Sentry.init({
dsn: process.env.SENTRY_DSN,
environment: process.env.NODE_ENV,
tracesSampleRate: 0.1,
});
Metrics (Datadog)
import StatsD from 'hot-shots';
const metrics = new StatsD({
host: 'localhost',
port: 8125,
prefix: 'chatsdk.',
});
metrics.increment('messages.sent');
metrics.histogram('messages.latency', messageLatency);
Backup Strategy
# Daily database backups
pg_dump -h your-db-host -U chatsdk chatsdk_production \
| gzip > backup-$(date +%Y%m%d).sql.gz
# Upload to S3
aws s3 cp backup-$(date +%Y%m%d).sql.gz \
s3://your-backup-bucket/db-backups/
# Retain backups for 30 days
SSL/TLS Configuration
# Let's Encrypt with Certbot
certbot --nginx -d api.yourdomain.com
# Nginx SSL config
ssl_certificate /etc/letsencrypt/live/api.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.yourdomain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
CDN Setup
# CloudFlare
# 1. Add domain to CloudFlare
# 2. Enable caching for static assets
# 3. Enable WebSocket proxying
# CloudFront (AWS)
aws cloudfront create-distribution \
--origin-domain-name api.yourdomain.com \
--default-cache-behavior MinTTL=0,MaxTTL=31536000
Production Checklist
Before going live:
- Set all environment variables
- Enable HTTPS/SSL
- Configure CORS properly
- Set up database backups
- Enable error tracking (Sentry)
- Configure logging
- Set up monitoring/alerts
- Load test with expected traffic
- Enable rate limiting
- Review security settings
- Configure CDN for static assets
- Set up CI/CD pipeline
- Prepare rollback plan
- Document deployment process
Next Steps
- Security → - Security best practices
- Performance → - Optimization tips
- Monitoring Guide → - Detailed monitoring setup