OS Trading Engine
Self-Hosting
Production Checklist

Production Checklist

Ensure your Nexgent deployment is secure, performant, and production-ready.


Required Environment Variables

Before deploying, ensure these required variables are set:

VariableRequiredDescription
DATABASE_URL✅ YesPostgreSQL connection string
JWT_SECRET✅ YesMinimum 32 characters (validated at startup)
NEXTAUTH_SECRET✅ YesNextAuth.js secret (frontend)
NEXTAUTH_URL✅ YesYour frontend URL
CORS_ORIGIN✅ YesYour frontend domain(s), comma-separated
🚫

The backend will fail to start if DATABASE_URL or JWT_SECRET (under 32 chars) are missing.


Security Checklist

Environment & Secrets

  • Strong JWT secret - At least 32 characters, randomly generated

    openssl rand -base64 32
  • Strong NextAuth secret - Separate from JWT secret

    openssl rand -base64 32
  • Strong database password - At least 24 characters with mixed case, numbers, symbols

  • No secrets in code - All secrets in environment variables only

  • .env files in .gitignore - Never commit secrets

Network Security

  • HTTPS only - All traffic encrypted with TLS 1.2+
  • CORS configured - Only allow your frontend domain
    CORS_ORIGIN=https://your-domain.com
  • Database not publicly accessible - Bind to localhost or use firewall
  • Redis not publicly accessible - Bind to localhost or use firewall
  • Firewall configured - Only allow ports 22, 80, 443

Application Security

  • NODE_ENV=production - Disables debug features
  • Account lockout active - 5 failed attempts = 15 min lockout

Database Configuration

PostgreSQL Best Practices

Connection Pooling

For production with multiple connections:

# Backend .env
DATABASE_URL="postgresql://user:pass@host:5432/nexgent?schema=public&connection_limit=20"

Performance Tuning

If self-hosting PostgreSQL, edit postgresql.conf:

# Memory (adjust based on available RAM)
shared_buffers = 256MB           # 25% of RAM
effective_cache_size = 768MB     # 75% of RAM
work_mem = 16MB
 
# Connections
max_connections = 100
 
# Write performance
wal_buffers = 16MB
checkpoint_completion_target = 0.9
 
# Query planning
random_page_cost = 1.1           # For SSD storage
effective_io_concurrency = 200   # For SSD storage

Managed Database Services

For easier operations, consider these PostgreSQL providers:

ProviderProsStarting Price
SupabaseFree tier, Postgres extensions, easy setupFree
NeonServerless Postgres, branching, autoscalingFree tier
Railway PostgreSQLEasy, integrated with Railway deployments$5/month
Vercel PostgresIntegrated with Vercel deployments$20/month
AWS RDSEnterprise-grade, automated backups~$15/month
⚠️

Nexgent requires PostgreSQL. MySQL-compatible services like PlanetScale are not supported.

Backups

Automated daily backups:

#!/bin/bash
# /home/nexgent/backup-db.sh
 
BACKUP_DIR="/backups/postgres"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=30
 
mkdir -p $BACKUP_DIR
 
# Create backup
PGPASSWORD=$DB_PASSWORD pg_dump \
  -h localhost \
  -U nexgent \
  -d nexgent \
  -F custom \
  -f "$BACKUP_DIR/nexgent_$TIMESTAMP.dump"
 
# Compress
gzip "$BACKUP_DIR/nexgent_$TIMESTAMP.dump"
 
# Remove old backups
find $BACKUP_DIR -name "*.gz" -mtime +$RETENTION_DAYS -delete

Schedule with cron:

0 3 * * * /home/nexgent/backup-db.sh >> /var/log/nexgent/backup.log 2>&1

Restore from backup:

gunzip -c nexgent_20250120.dump.gz | pg_restore -h localhost -U nexgent -d nexgent

Redis Configuration

Production Settings

Edit /etc/redis/redis.conf (or equivalent):

# Security
requirepass your-strong-redis-password
bind 127.0.0.1
 
# Memory management
maxmemory 256mb
maxmemory-policy allkeys-lru
 
# Persistence (optional, for cache it's not critical)
save 900 1
save 300 10
save 60 10000
 
# Performance
tcp-keepalive 300

Managed Redis Services

ProviderProsStarting Price
Railway RedisEasy, integrated$5/month
UpstashServerless, per-request pricingFree tier
Redis CloudOfficial Redis, high availabilityFree tier
AWS ElastiCacheEnterprise-grade~$15/month

Redis Connection Configuration

# Standard configuration
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=your-strong-redis-password
REDIS_DB=0
REDIS_KEY_PREFIX=nexgent:
 
# Railway/managed service alternatives (also supported)
REDISHOST=localhost
REDISPORT=6379
REDISPASSWORD=your-strong-redis-password

Nexgent supports both REDIS_HOST and REDISHOST naming conventions for compatibility with different hosting platforms.


SSL/TLS Configuration

Certbot (Let's Encrypt)

Initial setup:

sudo certbot --nginx -d your-domain.com -d api.your-domain.com

Auto-renewal:

# Test renewal
sudo certbot renew --dry-run
 
# Certbot auto-installs a cron job, but verify:
sudo systemctl status certbot.timer

Nginx SSL Configuration

After Certbot runs, enhance security in /etc/nginx/sites-available/nexgent:

server {
    listen 443 ssl http2;
    server_name your-domain.com;
 
    # SSL certificates (managed by Certbot)
    ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
 
    # SSL configuration
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
 
    # Security headers
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
 
    # ... rest of config
}
 
# Redirect HTTP to HTTPS
server {
    listen 80;
    server_name your-domain.com api.your-domain.com;
    return 301 https://$server_name$request_uri;
}

Vercel/Railway SSL

Both platforms automatically provision and manage SSL certificates for custom domains. No manual configuration needed.


Monitoring

Health Endpoints

Nexgent provides these health endpoints:

EndpointPurposeChecks
/api/v1/healthFull health checkDatabase, Redis, queue status. Returns healthy, degraded, or unhealthy
/api/v1/readyKubernetes readiness probeDatabase (required), Redis (preferred). Returns 503 if not ready
/api/v1/liveKubernetes liveness probeProcess running only. Always returns 200 if server responds
/api/v1/metricsPrometheus metricsApplication metrics in Prometheus format

Uptime Monitoring

Set up external monitoring with:

Monitor:

  • https://your-domain.com (frontend)
  • https://api.your-domain.com/api/v1/health (backend)

Logging

PM2 Logs

pm2 logs --lines 100
pm2 logs nexgent-backend
pm2 logs nexgent-frontend

Centralized Logging (Optional)

For production, consider:

Log Rotation

sudo nano /etc/logrotate.d/nexgent
/home/nexgent/logs/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 0640 nexgent nexgent
}

Prometheus Metrics (Optional)

If using Prometheus for monitoring, configure it to scrape the metrics endpoint:

# prometheus.yml
scrape_configs:
  - job_name: 'nexgent'
    static_configs:
      - targets: ['api.your-domain.com']
    metrics_path: '/api/v1/metrics'
    scheme: https

Test the endpoint:

curl https://api.your-domain.com/api/v1/metrics

Performance Optimization

Node.js

# Increase memory limit if needed
NODE_OPTIONS="--max-old-space-size=512"

Nginx Caching (Optional)

For static assets:

location /_next/static {
    proxy_pass http://127.0.0.1:3000;
    proxy_cache_valid 200 365d;
    add_header Cache-Control "public, immutable";
}

Database Indexes

Prisma migrations include necessary indexes. Verify with:

-- Check existing indexes
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'public';

Disaster Recovery

Recovery Time Objective (RTO)

ScenarioTarget RTO
Application crash< 5 minutes (PM2 auto-restart)
Server failure< 1 hour (restore from snapshot)
Data corruption< 4 hours (restore from backup)

Recovery Plan

  1. Application failure: PM2 auto-restarts
  2. Server failure:
    • Restore from VPS snapshot
    • Or redeploy to new server
  3. Data loss:
    • Restore database from backup
    • Redis cache rebuilds automatically

Testing Recovery

Regularly test your recovery procedures:

# Test database restore
pg_restore -h localhost -U nexgent -d nexgent_test backup.dump
 
# Test application restart
pm2 kill && pm2 start ecosystem.config.js

Final Checklist

Before Going Live

  • All environment variables set
  • Database migrations applied
  • SSL certificates installed
  • CORS configured correctly
  • Firewall configured
  • Backups scheduled
  • Monitoring set up
  • Health checks passing
  • Tested login/registration flow
  • Tested trading flow (simulation mode)

Post-Launch

  • Monitor error logs for first 24-48 hours
  • Verify backup jobs are running
  • Check SSL certificate expiry dates
  • Test recovery procedures
  • Document any custom configurations