Aller au contenu principal

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

  1. Connect your GitHub repository
  2. Configure environment variables in the dashboard
  3. Auto-deploys on git push

Database Setup

  1. Create cluster at mongodb.com/cloud/atlas
  2. Whitelist your server IP
  3. Create database user
  4. Get connection string
  5. Update DATABASE_URL in .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

  1. Create account at redis.com/try-free
  2. Create database
  3. Get connection details
  4. Update REDIS_HOST, REDIS_PORT, REDIS_PASSWORD in .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