Deployment Guide
This guide covers deploying Express Backend TS to production environments.
Pre-Deployment Checklist
Before deploying to production, ensure you have:
- Changed all default secrets and passwords
- Configured production database (MongoDB Atlas recommended)
- Set up Redis instance (Redis Cloud, AWS ElastiCache, etc.)
- Configured production SMTP service for emails
- Set
APP_MODE=PRODUCTION - Enabled HTTPS/SSL
- Configured CORS for your frontend domain
- Set up proper logging and monitoring
- Created backup strategy
- Tested all critical endpoints
Environment Configuration
Production Environment Variables
# Application
APP_NAME="YourAppName"
APP_MODE=PRODUCTION
APP_PORT=3000
APP_URL=https://api.yourdomain.com
APP_URL_FRONTEND=https://yourdomain.com
APP_PREFIX_ROUTES=/api
APP_VERSION=1.0.0
# Rate Limiting (Stricter in production)
RATE_LIMIT_WINDOW_MS=60000
RATE_LIMIT_MAX_REQUESTS=100
RATE_LIMIT_SKIP_IPS=""
# API Security
X_API_KEY=your-strong-random-api-key-here
# Allowed Elements
ALLOWED_SUPPORTED_LANGUAGES=fr,en
ALLOWED_ORIGINS=https://yourdomain.com
ALLOWED_METHODS=OPTIONS,HEAD,GET,POST,PUT,DELETE,PATCH
# Feature Toggles
USE_DATABASE=yes
USE_RATELIMIT=yes
USE_MAIL=yes
USE_QUEUE=yes
USE_CACHE=yes
SAVE_LOGS=yes
# Database (MongoDB Atlas recommended)
DATABASE_URL="mongodb+srv://username:password@cluster.mongodb.net/production?retryWrites=true&w=majority"
DATABASE_MAX_POOL_SIZE=50
DATABASE_MIN_POOL_SIZE=10
DATABASE_SERVER_TIMEOUT=5000
DATABASE_SOCKET_TIMEOUT=45000
DATABASE_CONNECT_TIMEOUT=10000
DATABASE_HEARTBEAT_FREQ=10000
# Redis (Production instance)
REDIS_QUEUE=production
REDIS_HOST=your-redis-host.com
REDIS_PORT=6379
REDIS_PASSWORD=your-strong-redis-password
# Authentication (CRITICAL: Use strong secrets!)
SECRET_TOKEN=your-very-strong-secret-token-min-64-chars
COOKIE_SECRET=your-very-strong-cookie-secret-min-32-chars
# Templates
TEMPLATE_PATH=templates
# Production Email (SMTP)
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_SERVICE=gmail
MAIL_SENSER_NAME="Your Company Name"
MAIL_SENSER_EMAIL="noreply@yourdomain.com"
MAIL_SECURE=true
MAIL_USER=your-email@gmail.com
MAIL_PASSWORD=your-gmail-app-password
# Admin User (created by seeders)
USER_LASTNAME=Admin
USER_FIRSTNAME=System
USER_USERNAME=admin
USER_EMAIL=admin@yourdomain.com
USER_PASSWORD=STRONG_PASSWORD_HERE
# Logging (Production settings)
LOGGING_ENABLED=true
LOGGING_TO_FILE=true
LOGGING_TO_DATABASE=true
MAX_LOG_QUEUE_SIZE=5000
LOG_BATCH_SIZE=50
LOG_PROCESS_INTERVAL=3000
LOG_CLEANUP_DAYS=90
MAX_REQUEST_SIZE=5mb
LOGS_DIR=/var/log/expressbase
Deployment Options
Option 1: Traditional VPS/Server (DigitalOcean, AWS EC2, etc.)
1. Server Setup
# Update system
sudo apt update && sudo apt upgrade -y
# Install Node.js 18+
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs
# Install MongoDB (or use MongoDB Atlas)
wget -qO - https://www.mongodb.org/static/pgp/server-5.0.asc | sudo apt-key add -
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/5.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-5.0.list
sudo apt-get update
sudo apt-get install -y mongodb-org
# Install Redis
sudo apt install redis-server -y
# Install Nginx
sudo apt install nginx -y
# Install PM2 (Process Manager)
sudo npm install -g pm2
2. Deploy Application
# Clone repository
cd /var/www
git clone https://github.com/yourusername/your-project.git
cd your-project
# Install dependencies
npm install --production
# Configure environment
nano .env
# Add all production variables (see above)
# Build TypeScript
npm run build
# Start with PM2
pm2 start dist/main.js --name "express-api"
pm2 save
pm2 startup
3. Configure Nginx
server {
listen 80;
server_name api.yourdomain.com;
# Client body size
client_max_body_size 10M;
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;
# Timeouts
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}
4. Enable HTTPS with Let's Encrypt
# Install Certbot
sudo apt install certbot python3-certbot-nginx -y
# Get SSL certificate
sudo certbot --nginx -d api.yourdomain.com
# Auto-renewal test
sudo certbot renew --dry-run
Option 2: Docker Deployment
Docker Compose Production Setup
version: '3.8'
services:
app:
build: .
ports:
- "3000:3000"
environment:
APP_MODE: PRODUCTION
env_file:
- .env.production
depends_on:
- mongodb
- redis
restart: unless-stopped
volumes:
- ./templates:/app/templates
- ./logs:/app/.logs
mongodb:
image: mongo:5.0
ports:
- "27017:27017"
environment:
MONGO_INITDB_ROOT_USERNAME: ${MONGODB_USER}
MONGO_INITDB_ROOT_PASSWORD: ${MONGODB_PASSWORD}
volumes:
- mongodb_data:/data/db
restart: unless-stopped
redis:
image: redis:7-alpine
ports:
- "6379:6379"
command: redis-server --requirepass ${REDIS_PASSWORD}
volumes:
- redis_data:/data
restart: unless-stopped
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./ssl:/etc/nginx/ssl
depends_on:
- app
restart: unless-stopped
volumes:
mongodb_data:
redis_data:
# Build and start
docker-compose -f docker-compose.prod.yml up -d
# View logs
docker-compose logs -f app
# Stop
docker-compose down
Option 3: Cloud Platforms
Heroku
# Login to Heroku
heroku login
# Create app
heroku create your-app-name
# Add MongoDB addon
heroku addons:create mongolab:sandbox
# Add Redis addon
heroku addons:create heroku-redis:hobby-dev
# Set environment variables
heroku config:set APP_MODE=PRODUCTION
heroku config:set SECRET_TOKEN=your-secret
heroku config:set COOKIE_SECRET=your-cookie-secret
# ... set all env vars
# Deploy
git push heroku main
# Scale
heroku ps:scale web=1
AWS Elastic Beanstalk
# Install EB CLI
pip install awsebcli
# Initialize
eb init
# Create environment
eb create production
# Deploy
eb deploy
# View logs
eb logs
DigitalOcean App Platform
- Connect your GitHub repository
- Configure environment variables in the dashboard
- Auto-deploys on git push
Database Setup
MongoDB Atlas (Recommended)
- Create cluster at mongodb.com/cloud/atlas
- Whitelist your server IP
- Create database user
- Get connection string
- Update
DATABASE_URLin.env
Self-Hosted MongoDB
# Secure MongoDB
mongosh
use admin
db.createUser({
user: "admin",
pwd: "secure_password",
roles: ["root"]
})
# Enable authentication in /etc/mongod.conf
security:
authorization: enabled
# Restart MongoDB
sudo systemctl restart mongod
Redis Setup
Redis Cloud (Recommended)
- Create account at redis.com/try-free
- Create database
- Get connection details
- Update
REDIS_HOST,REDIS_PORT,REDIS_PASSWORDin.env
Self-Hosted Redis
# Secure Redis
sudo nano /etc/redis/redis.conf
# Add password
requirepass your_secure_password
# Bind to localhost only (if on same server)
bind 127.0.0.1
# Restart Redis
sudo systemctl restart redis
Monitoring & Logging
PM2 Monitoring
# View status
pm2 status
# View logs
pm2 logs express-api
# Monitor resources
pm2 monit
# Restart on errors
pm2 start dist/main.js --name express-api --max-restarts 10
Application Logs
Logs are automatically written to:
.logs/error.log- Error logs (or LOGS_DIR in production).logs/combined.log- All logs- MongoDB collection - Database logs
Configure log rotation in your server:
# /etc/logrotate.d/expressbase
/var/log/expressbase/*.log {
daily
rotate 14
compress
delaycompress
notifempty
create 0640 www-data www-data
sharedscripts
postrotate
pm2 reload express-api
endscript
}
Performance Optimization
Enable Production Mode
# Always set APP_MODE=PRODUCTION
APP_MODE=PRODUCTION npm start
Use Redis Caching
Ensure Redis is configured and USE_CACHE=yes in production.
Database Indexing
Indexes are automatically created by models. Verify in MongoDB:
// In mongosh
db.users.getIndexes()
db.login_histories.getIndexes()
Security Hardening
1. Use Strong Secrets
# Generate strong secrets
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
2. Enable Rate Limiting
Already configured via USE_RATELIMIT=yes. Adjust limits in environment:
RATE_LIMIT_WINDOW_MS=60000
RATE_LIMIT_MAX_REQUESTS=100
3. Configure CORS Properly
# Only allow your production frontend
ALLOWED_ORIGINS=https://yourdomain.com
4. Use HTTPS Only
Let's Encrypt provides free SSL certificates (see above).
Backup Strategy
MongoDB Backups
# Manual backup
mongodump --uri="mongodb+srv://user:pass@cluster.mongodb.net/database" --out=/backups/$(date +%Y%m%d)
# Automated daily backup (crontab)
0 2 * * * /usr/bin/mongodump --uri="..." --out=/backups/$(date +%Y%m%d) >> /var/log/mongodb-backup.log 2>&1
Redis Backups
# Enable AOF persistence (in redis.conf)
appendonly yes
appendfilename "appendonly.aof"
# Or use RDB snapshots
save 900 1
save 300 10
save 60 10000
Troubleshooting
Application Won't Start
# Check logs
pm2 logs express-api --lines 100
# Check environment
pm2 env 0
# Restart
pm2 restart express-api
Database Connection Issues
# Test MongoDB connection
mongosh "mongodb+srv://user:pass@cluster.mongodb.net/database"
# Check network
ping cluster.mongodb.net
Redis Connection Issues
# Test Redis connection
redis-cli -h your-redis-host.com -p 6379 -a your-password ping
# Should respond: PONG
Email Not Sending
Check the logs for email queue errors. Common issues:
# For Gmail:
# 1. Enable 2FA on your Google account
# 2. Generate App Password (not regular password)
# 3. Use App Password in MAIL_PASSWORD
# Test SMTP connection
telnet smtp.gmail.com 587
Maintenance
Update Dependencies
# Check for updates
npm outdated
# Update
npm update
# Rebuild and redeploy
npm run build
pm2 restart express-api
Database Migrations
# Run seeders in production (first time only)
APP_MODE=PRODUCTION node utils/seeders/run.js
Performance Benchmarks
Expected performance in production:
- Authentication: < 1ms (with Redis cache)
- Database Queries: 10-50ms (depends on query and indexing)
- API Responses: 50-200ms (average)
- File Upload: Depends on file size and network
- Queue Processing: Background, non-blocking
Support
For production issues:
- GitHub Issues: [Repository Issues Page]
- Email: Contact your support team
Next: Environment Configuration - Detailed variable reference