Server Configuration & Deployment
Production deployment, security, and optimization guide
Production Environment Setup
This guide covers deploying ManageX in a production environment with proper security, performance, and monitoring configurations.
Server Requirements
- CPU: 2+ cores (4+ recommended)
- RAM: 8GB minimum (16GB+ recommended)
- Storage: 50GB+ SSD storage
- OS: Ubuntu 20.04 LTS or CentOS 8+
- Network: Static IP address, domain name
Environment Configuration
Production .env Configuration
Create a .env file in the server directory with your production configuration:
Example .env File
# NODE Configuration PORT=3000 NODE_ENV=production # Database Configuration DB_HOST=localhost DB_NAME=managex_db DB_USERNAME=managex_user DB_PASSWORD=your_secure_password DB_DIALECT=mysql # JWT Configuration JWT_SECRET=your-super-secure-jwt-secret-key-change-this-in-production JWT_REFRESH_SECRET=your-refresh-secret-key-change-in-production JWT_EXPIRES_IN=24h JWT_REFRESH_EXPIRES_IN=7d # Demo Mode Configuration IS_DEMO=0
Security Warning
Never commit the .env file to version control. Use environment-specific configuration files and secure secret management. Change all default secrets and passwords in production.
Production Checklist
- Set
NODE_ENV=productionfor optimal performance - Use strong, unique passwords for database and JWT secrets
- Set
IS_DEMO=0to skip demo data seeders - Configure proper email settings for notifications
- Update
APP_URLto your production domain
Process Management
PM2 Configuration
Create ecosystem.config.js for production deployment:
module.exports = {
apps: [{
name: 'managex-server',
script: './bin/www',
instances: 'max', // Use all CPU cores
exec_mode: 'cluster',
autorestart: true,
watch: false,
max_memory_restart: '1G',
env: {
NODE_ENV: 'production',
PORT: 3000
},
error_file: './logs/err.log',
out_file: './logs/out.log',
log_file: './logs/combined.log',
time: true,
log_date_format: 'YYYY-MM-DD HH:mm:ss Z'
}]
};
Systemd Service
Create /etc/systemd/system/managex.service:
[Unit] Description=ManageX Business Management System After=network.target mysql.service Requires=mysql.service [Service] Type=forking User=www-data Group=www-data WorkingDirectory=/var/www/managex/server ExecStart=/usr/bin/pm2 start ecosystem.config.js ExecReload=/usr/bin/pm2 reload all ExecStop=/usr/bin/pm2 stop all Restart=always RestartSec=10 [Install] WantedBy=multi-user.target
Enable and Start Service
# Reload systemd sudo systemctl daemon-reload # Enable service to start on boot sudo systemctl enable managex # Start service sudo systemctl start managex # Check status sudo systemctl status managex
Web Server Configuration
Nginx Configuration
Create /etc/nginx/sites-available/managex:
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name yourdomain.com www.yourdomain.com;
# SSL Configuration
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
ssl_prefer_server_ciphers off;
# Security Headers
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# Rate Limiting
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login:10m rate=1r/s;
# API Routes
location /api/ {
limit_req zone=api burst=20 nodelay;
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;
}
# Application (EJS server-side rendering)
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;
}
# File uploads
location /uploads/ {
alias /var/www/managex/server/public/uploads/;
expires 1y;
add_header Cache-Control "public";
}
# Static assets
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
root /var/www/managex/server/public;
expires 1y;
add_header Cache-Control "public, immutable";
}
}
Enable Nginx Site
# Create symbolic link sudo ln -s /etc/nginx/sites-available/managex /etc/nginx/sites-enabled/ # Test configuration sudo nginx -t # Reload Nginx sudo systemctl reload nginx
Apache Configuration
Create /etc/apache2/sites-available/managex.conf:
<VirtualHost *:80>
ServerName yourdomain.com
ServerAlias www.yourdomain.com
Redirect permanent / https://yourdomain.com/
</VirtualHost>
<VirtualHost *:443>
ServerName yourdomain.com
ServerAlias www.yourdomain.com
# SSL Configuration
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/yourdomain.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/yourdomain.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/yourdomain.com/chain.pem
# Security Headers
Header always set X-Frame-Options DENY
Header always set X-Content-Type-Options nosniff
Header always set X-XSS-Protection "1; mode=block"
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
# API Proxy
ProxyPreserveHost On
ProxyPass /api/ http://localhost:3000/api/
ProxyPassReverse /api/ http://localhost:3000/api/
# Application Proxy
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/
# File uploads
Alias /uploads /var/www/managex/server/public/uploads
<Directory /var/www/managex/server/public/uploads>
Options -Indexes
AllowOverride None
Require all granted
</Directory>
</VirtualHost>
Enable Apache Modules and Site
# Enable required modules sudo a2enmod proxy sudo a2enmod proxy_http sudo a2enmod ssl sudo a2enmod headers sudo a2enmod rewrite # Enable site sudo a2ensite managex.conf # Test configuration sudo apache2ctl configtest # Reload Apache sudo systemctl reload apache2
SSL Certificate Setup
Let's Encrypt with Certbot
Install Certbot
# Ubuntu/Debian sudo apt update sudo apt install certbot python3-certbot-nginx # CentOS/RHEL sudo yum install certbot python3-certbot-nginx
Obtain Certificate
# For Nginx sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com # For Apache sudo certbot --apache -d yourdomain.com -d www.yourdomain.com
Follow the prompts to complete the certificate installation.
Auto-renewal
# Test renewal sudo certbot renew --dry-run # Add to crontab for auto-renewal sudo crontab -e # Add: 0 12 * * * /usr/bin/certbot renew --quiet
Monitoring and Logging
Log Management
Configure log rotation in /etc/logrotate.d/managex:
/var/www/managex/server/logs/*.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 644 www-data www-data
postrotate
/usr/bin/pm2 reloadLogs
endscript
}
Health Monitoring
Set up monitoring with tools like:
- PM2 Monitoring: Built-in process monitoring with
pm2 monit - Uptime Robot: External uptime monitoring
- New Relic: Application performance monitoring
- DataDog: Infrastructure monitoring
- Grafana + Prometheus: Custom monitoring dashboards
Backup Strategy
#!/bin/bash # Database backup script DATE=$(date +%Y%m%d_%H%M%S) BACKUP_DIR="/var/backups/managex" DB_NAME="managex_db" DB_USER="managex_user" DB_PASSWORD="your_password" # Create backup directory mkdir -p $BACKUP_DIR # Backup database mysqldump -u $DB_USER -p$DB_PASSWORD $DB_NAME > $BACKUP_DIR/db_backup_$DATE.sql # Compress backup gzip $BACKUP_DIR/db_backup_$DATE.sql # Backup uploads tar -czf $BACKUP_DIR/uploads_backup_$DATE.tar.gz /var/www/managex/server/public/uploads/ # Keep only last 30 days of backups find $BACKUP_DIR -name "*.sql.gz" -mtime +30 -delete find $BACKUP_DIR -name "*.tar.gz" -mtime +30 -delete # Optional: Upload to cloud storage (AWS S3, etc.) # aws s3 cp $BACKUP_DIR/db_backup_$DATE.sql.gz s3://your-bucket/backups/
Automated Backups
Add the backup script to crontab to run daily:
# Edit crontab sudo crontab -e # Add daily backup at 2 AM 0 2 * * * /path/to/backup-script.sh
Security Hardening
Server Security
- Keep the system and packages updated regularly
- Configure firewall (UFW or iptables) to allow only necessary ports
- Disable root login and use SSH keys for authentication
- Install fail2ban for brute force protection
- Use non-standard ports for SSH (if applicable)
- Enable automatic security updates
Application Security
- Use environment variables for all sensitive data
- Implement proper input validation and sanitization
- Use HTTPS everywhere (enforce SSL/TLS)
- Set secure HTTP headers (XSS protection, content type, etc.)
- Regular security audits and dependency updates
- Implement rate limiting on API endpoints
- Use strong JWT secrets and rotate them periodically
Database Security
- Use strong, unique passwords for database users
- Limit database user privileges (principle of least privilege)
- Enable SSL for database connections in production
- Regular security updates for MySQL
- Monitor database access logs
- Restrict database access to localhost only
- Regular database backups with encryption
Performance Optimization
Node.js Optimization
| Setting | Value | Description |
|---|---|---|
| NODE_ENV | production | Enables production optimizations |
| UV_THREADPOOL_SIZE | 128 | Increases thread pool size for better I/O performance |
| NODE_OPTIONS | --max-old-space-size=4096 | Increases memory limit to 4GB |
Database Optimization
- Add appropriate indexes on frequently queried columns
- Optimize slow queries using EXPLAIN
- Use connection pooling (Sequelize handles this automatically)
- Regular database maintenance (ANALYZE, OPTIMIZE)
- Monitor query performance and optimize as needed
- Consider read replicas for high-traffic scenarios
Caching Strategy
- Implement Redis for session storage (optional)
- Use CDN for static assets if serving large files
- Enable browser caching with proper cache headers
- Database query result caching for frequently accessed data
- Implement application-level caching for expensive operations
Deployment Checklist
Pre-deployment
- ✅ Test all functionality in staging environment
- ✅ Configure production environment variables
- ✅ Set up SSL certificates
- ✅ Configure web server (Nginx/Apache)
- ✅ Set up database with proper security
- ✅ Configure monitoring and logging
- ✅ Set up automated backup procedures
- ✅ Configure firewall rules
Deployment
- ✅ Deploy application code to production server
- ✅ Run database migrations (
npm run db:migrate) - ✅ Seed initial data if needed (
npm run demowithIS_DEMO=0) - ✅ Start application services (PM2 or systemd)
- ✅ Configure load balancer (if applicable)
- ✅ Test all endpoints and functionality
- ✅ Verify SSL certificate is working
- ✅ Test backup and restore procedures
Post-deployment
- ✅ Monitor application performance and resource usage
- ✅ Check error logs regularly
- ✅ Verify backup procedures are working
- ✅ Test failover and disaster recovery procedures
- ✅ Document any custom configurations
- ✅ Set up alerting for critical issues
- ✅ Schedule regular security updates
- ✅ Monitor database performance and optimize as needed