Skip to main content

Production Checklist

Before deploying to production, ensure you’ve completed these critical steps:
1

Security Configuration

CRITICAL: Generate a strong, random JWT secret:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
Update .env:
JWT_SECRET="your-generated-secret-here"
Never use the default JWT secret in production! This would allow attackers to forge authentication tokens.
All production deployments must use HTTPS:Option 1: Reverse Proxy (nginx)
server {
    listen 443 ssl http2;
    server_name yourdomain.com;
    
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
    
    # Client
    location / {
        root /path/to/client/dist;
        try_files $uri $uri/ /index.html;
    }
    
    # API
    location /api {
        proxy_pass http://localhost:3001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
    
    # WebSocket
    location /socket.io {
        proxy_pass http://localhost:3001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
    }
}
Option 2: Let’s Encrypt (Certbot)
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d yourdomain.com
  • Use strong database passwords (32+ random characters)
  • Enable SSL/TLS for database connections
  • Restrict database access to application servers only
  • Use connection pooling (Supabase pooler or PgBouncer)
  • Enable automatic backups
Supabase SSL Connection:
DATABASE_URL="postgresql://user:pass@host:6543/db?sslmode=require"
  • Never commit .env files to version control
  • Use platform-specific secrets management:
    • Vercel: Environment Variables in dashboard
    • Railway: Environment Variables in project settings
    • Docker: Use docker-compose.override.yml (gitignored)
  • Rotate secrets regularly
  • Use different secrets for different environments
2

Database Optimization

Apply all database migrations before starting the server:
npm run db:migrate
Verify schema is up to date:
cd server
npx prisma migrate status
For Supabase, use the Transaction pooler:
DATABASE_URL="postgresql://postgres.xxx:[email protected]:6543/postgres"
For self-hosted, configure PgBouncer (see Database Setup).
Automated backups (cron):
# Add to crontab: daily backup at 2 AM
0 2 * * * /usr/bin/docker exec neuron-meet-db pg_dump -U neuronmeet neuronmeet | gzip > /backups/neuronmeet-$(date +\%Y\%m\%d).sql.gz
Supabase: Backups are automatic on paid plans.
3

WebRTC Configuration

For production, configure a TURN server to ensure connectivity in restrictive networks:
TURN_SERVER_URL=turn:turn.yourdomain.com:3478
TURN_USERNAME=your-turn-username
TURN_PASSWORD=your-turn-password
Recommended TURN providers:
Without TURN, approximately 8-10% of users behind symmetric NATs or restrictive firewalls won’t be able to connect.
Install coturn on your server:
sudo apt install coturn
Configure /etc/turnserver.conf:
listening-port=3478
tls-listening-port=5349
listening-ip=YOUR_SERVER_IP
external-ip=YOUR_SERVER_IP
realm=yourdomain.com
server-name=yourdomain.com

lt-cred-mech
user=username:password

no-tcp-relay
no-multicast-peers

cert=/path/to/cert.pem
pkey=/path/to/key.pem
Enable and start:
sudo systemctl enable coturn
sudo systemctl start coturn
4

Performance Optimization

Set environment to production:
NODE_ENV=production
This enables:
  • Optimized builds
  • Reduced logging
  • Better error handling
  • Performance optimizations
Build both client and server:
npm run build
This runs:
  • Client: Vite production build with minification and tree-shaking
  • Server: NestJS compilation with TypeScript optimization
For global distribution, serve static assets from a CDN:Vercel: Automatic edge cachingCloudFlare:
  1. Add your domain to CloudFlare
  2. Enable “Cache Everything” page rule
  3. Configure SSL/TLS to “Full (strict)”
5

Monitoring & Logging

The server includes a health check endpoint:
GET /api/health
Configure uptime monitoring:
View logs by platform:Docker:
docker-compose logs -f server
Railway: View in Railway dashboard > Deployments > LogsPM2 (VPS):
pm2 logs neuron-meet
Consider integrating error tracking:

Platform-Specific Deployment

Docker Production Deployment

1

Update docker-compose.yml

Ensure production settings in docker-compose.yml:
environment:
  NODE_ENV: production
  JWT_SECRET: ${JWT_SECRET} # From .env file
2

Build and start services

docker-compose up -d --build
3

Verify services

docker-compose ps
All services should show “Up” status.

Vercel Deployment

Vercel is configured via vercel.json:
1

Install Vercel CLI

npm install -g vercel
2

Set environment variables

In Vercel dashboard, add:
  • VITE_API_URL - Your backend API URL
  • VITE_WS_URL - Your backend WebSocket URL
3

Deploy

vercel --prod
Vercel configuration includes security headers:
  • X-Content-Type-Options: nosniff
  • X-Frame-Options: DENY
  • X-XSS-Protection: 1; mode=block

Railway Deployment

Railway is configured via railway.json:
1

Connect repository

  1. Create Railway account
  2. New Project > Deploy from GitHub
  3. Select your repository
2

Add PostgreSQL

  • Click “New Service” > Database > PostgreSQL
  • Railway automatically provides DATABASE_URL
3

Configure environment

Add all environment variables in Railway dashboard.
4

Deploy

Railway automatically deploys on push to main branch.Configuration from railway.json:
  • Build: npm run build:production
  • Start: npm run start:production
  • Health check: /api/health (timeout: 100s)
  • Restart policy: ON_FAILURE (max 10 retries)

Manual VPS Deployment

For custom infrastructure:
1

Set up server

Requirements:
  • Ubuntu 20.04+ or similar
  • Node.js 18+
  • PostgreSQL 15+
  • nginx (reverse proxy)
  • PM2 (process manager)
2

Install dependencies

# Node.js
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install -y nodejs

# PM2
sudo npm install -g pm2

# nginx
sudo apt install -y nginx

# PostgreSQL
sudo apt install -y postgresql postgresql-contrib
3

Clone and build

git clone <repository-url>
cd neuron-meet
npm run install:all
npm run build
4

Configure PM2

Create ecosystem.config.js:
module.exports = {
  apps: [{
    name: 'neuron-meet',
    cwd: './server',
    script: 'dist/main.js',
    instances: 'max',
    exec_mode: 'cluster',
    env: {
      NODE_ENV: 'production',
      PORT: 3001
    }
  }]
};
Start with PM2:
pm2 start ecosystem.config.js
pm2 save
pm2 startup
5

Configure nginx

See the nginx configuration in Step 1 > Security Configuration > Enable HTTPS/TLSEnable and restart:
sudo ln -s /etc/nginx/sites-available/neuron-meet /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx

Scaling Considerations

Horizontal Scaling

For high traffic, scale across multiple servers:
Use nginx or a cloud load balancer:
upstream backend {
    least_conn;
    server backend1.example.com:3001;
    server backend2.example.com:3001;
    server backend3.example.com:3001;
}

server {
    location /api {
        proxy_pass http://backend;
    }
}
For WebSocket connections, enable sticky sessions:
upstream backend {
    ip_hash; # Sticky sessions based on IP
    server backend1.example.com:3001;
    server backend2.example.com:3001;
}
Or use Redis adapter for Socket.IO to share connections across servers.
  • Enable read replicas for read-heavy workloads
  • Use connection pooling (PgBouncer or Supabase pooler)
  • Consider database sharding for very large scale
  • Monitor query performance with Prisma logging

Vertical Scaling

Optimize resource usage:
  • CPU: Use PM2 cluster mode to utilize all cores
  • Memory: Monitor with pm2 monit and adjust limits
  • Database: Increase connection pool size for high concurrency

Security Hardening

These security measures are critical for production deployments.
Protect against abuse with rate limiting:
# In nginx config
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;

location /api {
    limit_req zone=api burst=20 nodelay;
    proxy_pass http://localhost:3001;
}
In production, restrict CORS to your frontend domain:
// server/src/main.ts
app.enableCors({
  origin: process.env.FRONTEND_URL,
  credentials: true
});
Already configured in vercel.json. For nginx:
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
Only expose necessary ports:
sudo ufw allow 22/tcp   # SSH
sudo ufw allow 80/tcp   # HTTP
sudo ufw allow 443/tcp  # HTTPS
sudo ufw enable
PostgreSQL and Node.js ports should only be accessible internally.

Post-Deployment Testing

1

Verify HTTPS

Test SSL/TLS configuration:
curl -I https://yourdomain.com
Check SSL grade at SSL Labs
2

Test API endpoints

# Health check
curl https://yourdomain.com/api/health

# Should return: {"status":"ok"}
3

Test WebRTC connectivity

  1. Create a test room
  2. Join from different networks (WiFi, mobile)
  3. Verify video/audio works
  4. Test screen sharing
  5. Verify TURN server is used in restrictive networks
4

Load testing

Use tools like Apache Bench or Artillery:
ab -n 1000 -c 10 https://yourdomain.com/api/health

Maintenance

Updates and Patches

git pull origin main
npm run install:all
npm run build

Monitoring Checklist

Server uptime and response times
Database connection pool usage
Disk space and database size
SSL certificate expiration
Error rates and exceptions
Active concurrent users

Troubleshooting

  • Verify nginx WebSocket proxy configuration
  • Check CORS settings allow WebSocket upgrade
  • Ensure sticky sessions are enabled for load balancing
  • Check firewall allows WebSocket traffic
  • Verify connection string and credentials
  • Check connection pool limits
  • Ensure database is accessible from app server
  • Review Prisma connection logs
  • Verify TURN server is configured and accessible
  • Check browser console for WebRTC errors
  • Test with different networks (WiFi, mobile, VPN)
  • Verify HTTPS is enabled (required for WebRTC)

Support

For deployment issues:
  1. Check application logs
  2. Review Environment Variables
  3. Verify Database Setup
  4. Consult platform documentation (Vercel, Railway, etc.)

Need Help?

If you encounter issues not covered in this guide, please open an issue on the GitHub repository with:
  • Deployment platform
  • Error logs
  • Configuration (with secrets redacted)

Build docs developers (and LLMs) love