Production Checklist
Ensure your Nexgent deployment is secure, performant, and production-ready.
Required Environment Variables
Before deploying, ensure these required variables are set:
| Variable | Required | Description |
|---|---|---|
DATABASE_URL | ✅ Yes | PostgreSQL connection string |
JWT_SECRET | ✅ Yes | Minimum 32 characters (validated at startup) |
NEXTAUTH_SECRET | ✅ Yes | NextAuth.js secret (frontend) |
NEXTAUTH_URL | ✅ Yes | Your frontend URL |
CORS_ORIGIN | ✅ Yes | Your 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
-
.envfiles 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 storageManaged Database Services
For easier operations, consider these PostgreSQL providers:
| Provider | Pros | Starting Price |
|---|---|---|
| Supabase | Free tier, Postgres extensions, easy setup | Free |
| Neon | Serverless Postgres, branching, autoscaling | Free tier |
| Railway PostgreSQL | Easy, integrated with Railway deployments | $5/month |
| Vercel Postgres | Integrated with Vercel deployments | $20/month |
| AWS RDS | Enterprise-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 -deleteSchedule with cron:
0 3 * * * /home/nexgent/backup-db.sh >> /var/log/nexgent/backup.log 2>&1Restore from backup:
gunzip -c nexgent_20250120.dump.gz | pg_restore -h localhost -U nexgent -d nexgentRedis 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 300Managed Redis Services
| Provider | Pros | Starting Price |
|---|---|---|
| Railway Redis | Easy, integrated | $5/month |
| Upstash | Serverless, per-request pricing | Free tier |
| Redis Cloud | Official Redis, high availability | Free tier |
| AWS ElastiCache | Enterprise-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-passwordNexgent 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.comAuto-renewal:
# Test renewal
sudo certbot renew --dry-run
# Certbot auto-installs a cron job, but verify:
sudo systemctl status certbot.timerNginx 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:
| Endpoint | Purpose | Checks |
|---|---|---|
/api/v1/health | Full health check | Database, Redis, queue status. Returns healthy, degraded, or unhealthy |
/api/v1/ready | Kubernetes readiness probe | Database (required), Redis (preferred). Returns 503 if not ready |
/api/v1/live | Kubernetes liveness probe | Process running only. Always returns 200 if server responds |
/api/v1/metrics | Prometheus metrics | Application metrics in Prometheus format |
Uptime Monitoring
Set up external monitoring with:
- UptimeRobot (opens in a new tab) (free, 50 monitors)
- Better Uptime (opens in a new tab) (free tier)
- Pingdom (opens in a new tab) (paid)
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-frontendCentralized Logging (Optional)
For production, consider:
- Logtail (opens in a new tab) - Free tier
- Papertrail (opens in a new tab) - Free tier
- Datadog (opens in a new tab) - Paid
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: httpsTest the endpoint:
curl https://api.your-domain.com/api/v1/metricsPerformance 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)
| Scenario | Target RTO |
|---|---|
| Application crash | < 5 minutes (PM2 auto-restart) |
| Server failure | < 1 hour (restore from snapshot) |
| Data corruption | < 4 hours (restore from backup) |
Recovery Plan
- Application failure: PM2 auto-restarts
- Server failure:
- Restore from VPS snapshot
- Or redeploy to new server
- 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.jsFinal 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