---
description: How to deploy the backend to production
---

# Deployment Workflow

Follow these steps to deploy the E-Learning Platform backend to production.

---

## Prerequisites

- Production server with Node.js 18+
- PostgreSQL database
- MinIO/S3 storage
- Domain name and SSL certificate

---

## Step 1: Prepare Production Server

```bash
# 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 install -y nodejs

# Install PM2
sudo npm install -g pm2

# Install nginx
sudo apt install -y nginx

# Install certbot for SSL
sudo apt install -y certbot python3-certbot-nginx
```

---

## Step 2: Clone Repository

```bash
# Create app directory
sudo mkdir -p /var/www/elearning-backend
sudo chown $USER:$USER /var/www/elearning-backend

# Clone repository
cd /var/www/elearning-backend
git clone <repository-url> .
```

---

## Step 3: Install Dependencies

```bash
npm ci --production
```

---

## Step 4: Setup Environment Variables

Create `.env` file:

```bash
# Application
NODE_ENV=production
PORT=4000
APP_URL=https://api.elearning.com

# Database
DATABASE_URL=postgresql://user:password@db-host:5432/elearning_prod

# MinIO/S3
S3_ENDPOINT=https://s3.elearning.com
S3_ACCESS_KEY=<access-key>
S3_SECRET_KEY=<secret-key>
S3_BUCKET_COURSES=courses
S3_BUCKET_VIDEOS=videos
S3_BUCKET_DOCUMENTS=documents
S3_BUCKET_IMAGES=images
S3_BUCKET_ATTACHMENTS=attachments

# JWT
JWT_SECRET=<strong-random-secret>
JWT_EXPIRES_IN=24h

# Email
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=<email>
SMTP_PASSWORD=<password>
SMTP_FROM=noreply@elearning.com

# CORS
CORS_ORIGIN=https://elearning.com,https://admin.elearning.com

# Rate Limiting
RATE_LIMIT_WINDOW_MS=900000
RATE_LIMIT_MAX_REQUESTS=100
```

---

## Step 5: Run Database Migrations

```bash
npx prisma migrate deploy
```

---

## Step 6: Setup PM2

Create `ecosystem.config.js`:

```javascript
module.exports = {
  apps: [{
    name: 'elearning-backend',
    script: './src/server.js',
    instances: 'max',
    exec_mode: 'cluster',
    env: {
      NODE_ENV: 'production'
    },
    error_file: './logs/err.log',
    out_file: './logs/out.log',
    log_file: './logs/combined.log',
    time: true
  }]
};
```

Start application:

```bash
pm2 start ecosystem.config.js
pm2 save
pm2 startup
```

---

## Step 7: Configure Nginx

Create `/etc/nginx/sites-available/elearning-backend`:

```nginx
upstream backend {
    server localhost:4000;
}

server {
    listen 80;
    server_name api.elearning.com;

    # Redirect to HTTPS
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name api.elearning.com;

    # SSL Configuration
    ssl_certificate /etc/letsencrypt/live/api.elearning.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.elearning.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    # Security Headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    # Logging
    access_log /var/log/nginx/elearning-backend-access.log;
    error_log /var/log/nginx/elearning-backend-error.log;

    # File Upload Size
    client_max_body_size 500M;

    location / {
        proxy_pass http://backend;
        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 600s;
        proxy_send_timeout 600s;
        proxy_read_timeout 600s;
    }
}
```

Enable site:

```bash
sudo ln -s /etc/nginx/sites-available/elearning-backend /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
```

---

## Step 8: Setup SSL Certificate

```bash
sudo certbot --nginx -d api.elearning.com
```

---

## Step 9: Setup Monitoring

### PM2 Monitoring

```bash
pm2 install pm2-logrotate
pm2 set pm2-logrotate:max_size 10M
pm2 set pm2-logrotate:retain 30
```

### Health Check Endpoint

Add to your app:

```javascript
app.get('/health', (req, res) => {
  res.status(200).json({
    status: 'ok',
    timestamp: new Date().toISOString(),
    uptime: process.uptime()
  });
});
```

---

## Step 10: Setup Backup

Create backup script `/opt/scripts/backup-db.sh`:

```bash
#!/bin/bash
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/var/backups/elearning"
DB_NAME="elearning_prod"

mkdir -p $BACKUP_DIR

# Backup database
pg_dump $DB_NAME | gzip > $BACKUP_DIR/db_$DATE.sql.gz

# Keep only last 7 days
find $BACKUP_DIR -name "db_*.sql.gz" -mtime +7 -delete

echo "Backup completed: db_$DATE.sql.gz"
```

Add to crontab:

```bash
# Daily backup at 2 AM
0 2 * * * /opt/scripts/backup-db.sh
```

---

## Step 11: Verify Deployment

```bash
# Check PM2 status
pm2 status

# Check logs
pm2 logs elearning-backend --lines 50

# Test health endpoint
curl https://api.elearning.com/health

# Test API
curl https://api.elearning.com/api/courses
```

---

## Update Deployment

```bash
# Pull latest code
cd /var/www/elearning-backend
git pull origin main

# Install dependencies
npm ci --production

# Run migrations
npx prisma migrate deploy

# Restart application
pm2 restart elearning-backend

# Check status
pm2 status
```

---

## Rollback

```bash
# Revert to previous commit
git reset --hard HEAD~1

# Reinstall dependencies
npm ci --production

# Rollback migration (if needed)
npx prisma migrate resolve --rolled-back <migration-name>

# Restart
pm2 restart elearning-backend
```

---

## Checklist

- [ ] Production server setup
- [ ] Repository cloned
- [ ] Dependencies installed
- [ ] Environment variables configured
- [ ] Database migrated
- [ ] PM2 configured and running
- [ ] Nginx configured
- [ ] SSL certificate installed
- [ ] Monitoring setup
- [ ] Backup script configured
- [ ] Health check working
- [ ] API endpoints tested

---

## Security Checklist

- [ ] Strong JWT secret
- [ ] Database credentials secured
- [ ] CORS configured correctly
- [ ] Rate limiting enabled
- [ ] SSL/TLS enabled
- [ ] Security headers configured
- [ ] File upload limits set
- [ ] Environment variables not in git
- [ ] Firewall configured
- [ ] SSH key-based authentication

---

## Monitoring

### PM2 Commands

```bash
# View logs
pm2 logs

# Monitor resources
pm2 monit

# Restart app
pm2 restart elearning-backend

# Stop app
pm2 stop elearning-backend

# Delete app
pm2 delete elearning-backend
```

### Check System Resources

```bash
# CPU and Memory
htop

# Disk usage
df -h

# Network connections
netstat -tulpn
```
