Production Deployment
This guide covers deploying OpenSNS to a production environment with proper security, HTTPS, and monitoring.
Production Checklist
Section titled “Production Checklist”Before going live, ensure:
- Strong, unique secrets for
JWT_SECRET_KEYandAPI_KEY_ENCRYPTION_KEY - HTTPS configured with valid SSL certificates
- Database backups configured
- Rate limiting enabled (built-in)
- CORS configured for your domain
- Monitoring and logging set up
Deployment Options
Section titled “Deployment Options”Option 1: VPS with Docker Compose
Section titled “Option 1: VPS with Docker Compose”Best for: Small to medium deployments, full control
Recommended providers: DigitalOcean, Linode, Vultr, Hetzner
# On your VPSgit clone https://github.com/yourusername/opensns.gitcd opensns
# Create production environment filecp .env.example .env# Edit .env with production valuesOption 2: Container Platform
Section titled “Option 2: Container Platform”Best for: Scaling, managed infrastructure
Recommended platforms:
- Railway
- Render
- Fly.io
- Google Cloud Run
- AWS ECS
Option 3: Kubernetes
Section titled “Option 3: Kubernetes”Best for: Large scale, complex requirements
See the Kubernetes section below.
Security Configuration
Section titled “Security Configuration”Generate Strong Secrets
Section titled “Generate Strong Secrets”# Generate JWT secret (64 characters)openssl rand -base64 48
# Generate encryption key (exactly 32 characters for AES-256)openssl rand -base64 24 | head -c 32Production Environment Variables
Section titled “Production Environment Variables”NODE_ENV=production
# Security (REQUIRED - use your generated values)JWT_SECRET_KEY=<your-64-char-random-string>API_KEY_ENCRYPTION_KEY=<your-32-char-random-string>
# DatabaseDATABASE_URL=postgresql://user:password@db-host:5432/opensns
# CORS - restrict to your domainCORS_ORIGINS=["https://yourdomain.com"]
# API Keys (optional - users can add their own)OPENAI_API_KEY=FAL_KEY=
# EnginesDEFAULT_LLM_ENGINE=openaiDEFAULT_IMAGE_ENGINE=falDEFAULT_VIDEO_ENGINE=fal-videoDatabase Security
Section titled “Database Security”- Use a managed database (AWS RDS, DigitalOcean Managed Database, etc.)
- Enable SSL connections
- Use strong, unique passwords
- Restrict network access to only your application servers
# Example: PostgreSQL with SSLDATABASE_URL=postgresql://user:pass@host:5432/opensns?sslmode=requireHTTPS with Nginx
Section titled “HTTPS with Nginx”Install Nginx and Certbot
Section titled “Install Nginx and Certbot”# Ubuntu/Debiansudo apt updatesudo apt install nginx certbot python3-certbot-nginxNginx Configuration
Section titled “Nginx Configuration”Create /etc/nginx/sites-available/opensns:
# Redirect HTTP to HTTPSserver { listen 80; server_name yourdomain.com; return 301 https://$server_name$request_uri;}
# Main HTTPS serverserver { listen 443 ssl http2; server_name yourdomain.com;
# SSL certificates (managed by Certbot) ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
# SSL settings ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256; ssl_prefer_server_ciphers off;
# Security headers add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Frontend location / { proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_cache_bypass $http_upgrade; }
# Backend API location /api/ { rewrite ^/api/(.*) /$1 break; proxy_pass http://localhost:8000; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme;
# Timeouts for long-running requests proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 300s; # 5 min for asset generation }
# WebSocket support location /ws { proxy_pass http://localhost:8000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_read_timeout 86400; }}Enable and Get SSL Certificate
Section titled “Enable and Get SSL Certificate”# Enable sitesudo ln -s /etc/nginx/sites-available/opensns /etc/nginx/sites-enabled/
# Test configurationsudo nginx -t
# Get SSL certificatesudo certbot --nginx -d yourdomain.com
# Reload Nginxsudo systemctl reload nginxProduction Docker Compose
Section titled “Production Docker Compose”Create docker-compose.prod.yml:
services: backend: build: context: ./backend dockerfile: Dockerfile restart: always environment: DATABASE_URL: ${DATABASE_URL} JWT_SECRET_KEY: ${JWT_SECRET_KEY} API_KEY_ENCRYPTION_KEY: ${API_KEY_ENCRYPTION_KEY} CORS_ORIGINS: '["https://yourdomain.com"]' ports: - "127.0.0.1:8000:8000" # Only localhost logging: driver: "json-file" options: max-size: "10m" max-file: "3"
frontend: build: context: ./frontend dockerfile: Dockerfile args: NEXT_PUBLIC_API_URL: https://yourdomain.com/api restart: always ports: - "127.0.0.1:3000:3000" # Only localhost logging: driver: "json-file" options: max-size: "10m" max-file: "3"Start with:
docker-compose -f docker-compose.prod.yml up -dDatabase Backups
Section titled “Database Backups”Automated Backups with Cron
Section titled “Automated Backups with Cron”Create /opt/opensns/backup.sh:
#!/bin/bashset -e
BACKUP_DIR="/opt/opensns/backups"TIMESTAMP=$(date +"%Y%m%d_%H%M%S")BACKUP_FILE="$BACKUP_DIR/opensns_$TIMESTAMP.sql.gz"
# Create backuppg_dump "$DATABASE_URL" | gzip > "$BACKUP_FILE"
# Keep only last 7 daysfind "$BACKUP_DIR" -name "*.sql.gz" -mtime +7 -delete
echo "Backup created: $BACKUP_FILE"Add to crontab:
# Run daily at 3 AM0 3 * * * /opt/opensns/backup.sh >> /var/log/opensns-backup.log 2>&1Offsite Backups
Section titled “Offsite Backups”Upload to S3 or similar:
# Install AWS CLIpip install awscli
# Add to backup scriptaws s3 cp "$BACKUP_FILE" "s3://your-bucket/opensns-backups/"Monitoring
Section titled “Monitoring”Health Checks
Section titled “Health Checks”The backend exposes a health endpoint:
curl https://yourdomain.com/api/healthUptime Monitoring
Section titled “Uptime Monitoring”Use services like:
- UptimeRobot (free)
- Better Uptime
- Pingdom
Configure to check:
https://yourdomain.com(frontend)https://yourdomain.com/api/health(backend)
Log Aggregation
Section titled “Log Aggregation”# View logsdocker-compose logs -f --tail=100
# Ship to external service (example: Papertrail)# Add to docker-compose.prod.yml:logging: driver: syslog options: syslog-address: "udp://logs.papertrailapp.com:12345"Kubernetes Deployment
Section titled “Kubernetes Deployment”For Kubernetes, create the following manifests:
Namespace
Section titled “Namespace”apiVersion: v1kind: Namespacemetadata: name: opensnsSecrets
Section titled “Secrets”apiVersion: v1kind: Secretmetadata: name: opensns-secrets namespace: opensnstype: OpaquestringData: jwt-secret-key: "your-jwt-secret" api-key-encryption-key: "your-encryption-key" database-url: "postgresql://..."Backend Deployment
Section titled “Backend Deployment”apiVersion: apps/v1kind: Deploymentmetadata: name: backend namespace: opensnsspec: replicas: 2 selector: matchLabels: app: backend template: metadata: labels: app: backend spec: containers: - name: backend image: your-registry/opensns-backend:latest ports: - containerPort: 8000 env: - name: DATABASE_URL valueFrom: secretKeyRef: name: opensns-secrets key: database-url - name: JWT_SECRET_KEY valueFrom: secretKeyRef: name: opensns-secrets key: jwt-secret-key resources: requests: memory: "256Mi" cpu: "250m" limits: memory: "512Mi" cpu: "500m" livenessProbe: httpGet: path: /health port: 8000 initialDelaySeconds: 10 periodSeconds: 10Scaling Considerations
Section titled “Scaling Considerations”Horizontal Scaling
Section titled “Horizontal Scaling”- Backend is stateless - scale with multiple replicas
- Use a load balancer (Nginx, HAProxy, cloud LB)
- Ensure database can handle connection pooling
Caching
Section titled “Caching”Add Redis for session caching and rate limiting:
redis: image: redis:7-alpine restart: always ports: - "127.0.0.1:6379:6379"CDN for Assets
Section titled “CDN for Assets”Store generated images/videos on a CDN:
- AWS S3 + CloudFront
- Cloudflare R2
- DigitalOcean Spaces
Troubleshooting
Section titled “Troubleshooting”502 Bad Gateway
Section titled “502 Bad Gateway”Backend not responding:
docker-compose logs backenddocker-compose restart backendDatabase Connection Issues
Section titled “Database Connection Issues”# Test database connectiondocker-compose exec backend python -c "from app.db import engine; print(engine.url)"SSL Certificate Renewal
Section titled “SSL Certificate Renewal”Certbot auto-renews, but verify:
sudo certbot renew --dry-runNext Steps
Section titled “Next Steps”- Set up monitoring dashboards (coming soon)
- Configure CI/CD pipelines (coming soon)
- Review security hardening (coming soon)