Production Deployment - openguard-bot/openguard GitHub Wiki

Production Deployment

This guide covers deploying AIMod in a production environment with high availability, security, and performance considerations.

🏗️ Production Architecture

Recommended Infrastructure

┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│   Load Balancer │    │   Web Server    │    │   Application   │
│   (Cloudflare)  │◄──►│   (Nginx)       │◄──►│   (AIMod Bot)   │
└─────────────────┘    └─────────────────┘    └─────────────────┘
                                │                       │
                                ▼                       ▼
┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│   Dashboard     │    │   Database      │    │   Cache         │
│   (React SPA)   │    │   (PostgreSQL)  │    │   (Redis)       │
└─────────────────┘    └─────────────────┘    └─────────────────┘

Server Specifications

Minimum Production Requirements:

  • CPU: 2 cores (4 cores recommended)
  • RAM: 4GB (8GB recommended)
  • Storage: 50GB SSD
  • Network: 100 Mbps connection
  • OS: Ubuntu 22.04 LTS or similar

Recommended Production Setup:

  • CPU: 4-8 cores
  • RAM: 8-16GB
  • Storage: 100GB+ NVMe SSD
  • Network: 1 Gbps connection
  • Backup: Automated daily backups

🚀 Deployment Process

1. Server Preparation

Initial Server Setup

# Update system
sudo apt update && sudo apt upgrade -y

# Install essential packages
sudo apt install -y curl wget git unzip software-properties-common

# Create application user
sudo useradd -m -s /bin/bash aimod
sudo usermod -aG sudo aimod

# Switch to application user
sudo su - aimod

Install Dependencies

# Install Python 3.11
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update
sudo apt install -y python3.11 python3.11-venv python3.11-dev

# Install Node.js 18
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install -y nodejs

# Install PostgreSQL 15
sudo apt install -y postgresql-15 postgresql-client-15 postgresql-contrib-15

# Install Redis
sudo apt install -y redis-server

# Install Nginx
sudo apt install -y nginx

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

2. Application Deployment

Clone and Setup Application

# Clone repository
cd /home/aimod
git clone https://github.com/discordaimod/aimod.git
cd aimod

# Create virtual environment
python3.11 -m venv venv
source venv/bin/activate

# Install Python dependencies
pip install -r requirements.txt

# Install production dependencies
pip install gunicorn supervisor

Environment Configuration

# Create production environment file
cp .env.example .env.production

# Edit production configuration
nano .env.production

Production Environment Variables:

# Discord Configuration
DISCORD_TOKEN=your_production_bot_token
DISCORD_CLIENT_ID=your_client_id
DISCORD_CLIENT_SECRET=your_client_secret

# Database Configuration
DATABASE_URL=postgresql://aimod_user:secure_password@localhost:5432/aimod_bot_prod
REDIS_URL=redis://localhost:6379/0

# AI Provider Configuration
OPENROUTER_API_KEY=your_production_api_key

# Security Configuration
JWT_SECRET=your_very_secure_jwt_secret_here
ENCRYPTION_KEY=your_32_byte_encryption_key_here

# Production Settings
ENVIRONMENT=production
DEBUG=false
LOG_LEVEL=INFO

# External Services
WEBHOOK_URL=https://your-webhook-endpoint.com
SENTRY_DSN=your_sentry_dsn_for_error_tracking

3. Database Setup

PostgreSQL Configuration

# Switch to postgres user
sudo su - postgres

# Create production database and user
psql << EOF
CREATE DATABASE aimod_bot_prod;
CREATE USER aimod_user WITH PASSWORD 'your_secure_password';
GRANT ALL PRIVILEGES ON DATABASE aimod_bot_prod TO aimod_user;
ALTER USER aimod_user CREATEDB;
\q
EOF

# Exit postgres user
exit

Database Security

# Edit PostgreSQL configuration
sudo nano /etc/postgresql/15/main/postgresql.conf

# Update settings:
# listen_addresses = 'localhost'
# max_connections = 100
# shared_buffers = 256MB
# effective_cache_size = 1GB

# Edit access control
sudo nano /etc/postgresql/15/main/pg_hba.conf

# Add secure access rules:
# local   aimod_bot_prod   aimod_user                     md5
# host    aimod_bot_prod   aimod_user   127.0.0.1/32      md5

# Restart PostgreSQL
sudo systemctl restart postgresql

Initialize Database

# Run database migrations
cd /home/aimod/aimod
source venv/bin/activate
python migrate_json_to_postgresql.py

# Verify database setup
python -c "
from database.connection import initialize_database
import asyncio
asyncio.run(initialize_database())
print('Database initialized successfully')
"

4. Redis Configuration

# Edit Redis configuration
sudo nano /etc/redis/redis.conf

# Update settings:
# bind 127.0.0.1
# port 6379
# requirepass your_redis_password
# maxmemory 512mb
# maxmemory-policy allkeys-lru

# Restart Redis
sudo systemctl restart redis-server
sudo systemctl enable redis-server

5. Application Services

Systemd Service for Bot

# Create systemd service file
sudo nano /etc/systemd/system/aimod-bot.service
[Unit]
Description=AIMod Discord Bot
After=network.target postgresql.service redis.service
Wants=postgresql.service redis.service

[Service]
Type=simple
User=aimod
Group=aimod
WorkingDirectory=/home/aimod/aimod
Environment=PATH=/home/aimod/aimod/venv/bin
EnvironmentFile=/home/aimod/aimod/.env.production
ExecStart=/home/aimod/aimod/venv/bin/python bot.py
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal

# Security settings
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/home/aimod/aimod

[Install]
WantedBy=multi-user.target

Systemd Service for Dashboard Backend

# Create dashboard backend service
sudo nano /etc/systemd/system/aimod-backend.service
[Unit]
Description=AIMod Dashboard Backend
After=network.target postgresql.service redis.service
Wants=postgresql.service redis.service

[Service]
Type=simple
User=aimod
Group=aimod
WorkingDirectory=/home/aimod/aimod/dashboard/backend
Environment=PATH=/home/aimod/aimod/venv/bin
EnvironmentFile=/home/aimod/aimod/.env.production
ExecStart=/home/aimod/aimod/venv/bin/gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker -b 127.0.0.1:8000
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal

# Security settings
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/home/aimod/aimod

[Install]
WantedBy=multi-user.target

Enable and Start Services

# Reload systemd
sudo systemctl daemon-reload

# Enable services
sudo systemctl enable aimod-bot.service
sudo systemctl enable aimod-backend.service

# Start services
sudo systemctl start aimod-bot.service
sudo systemctl start aimod-backend.service

# Check status
sudo systemctl status aimod-bot.service
sudo systemctl status aimod-backend.service

6. Frontend Deployment

Build Frontend

# Navigate to frontend directory
cd /home/aimod/aimod/dashboard/frontend

# Install dependencies
npm ci --production

# Create production environment
echo "REACT_APP_API_URL=https://yourdomain.com/api" > .env.production
echo "REACT_APP_DISCORD_CLIENT_ID=your_client_id" >> .env.production

# Build for production
npm run build

# Copy build to web directory
sudo mkdir -p /var/www/aimod-dashboard
sudo cp -r build/* /var/www/aimod-dashboard/
sudo chown -R www-data:www-data /var/www/aimod-dashboard

7. Nginx Configuration

Main Nginx Configuration

# Create Nginx configuration
sudo nano /etc/nginx/sites-available/aimod
# Rate limiting
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=auth:10m rate=5r/s;

server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;
    
    # Redirect to HTTPS
    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:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    
    # 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;
    add_header Referrer-Policy "strict-origin-when-cross-origin";
    add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; connect-src 'self' https://discord.com https://discordapp.com;";
    
    # Gzip compression
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json;
    
    # Frontend static files
    location / {
        root /var/www/aimod-dashboard;
        try_files $uri $uri/ /index.html;
        
        # Cache static assets
        location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
            expires 1y;
            add_header Cache-Control "public, immutable";
        }
    }
    
    # API endpoints
    location /api/ {
        limit_req zone=api burst=20 nodelay;
        
        proxy_pass http://127.0.0.1:8000;
        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;
        
        # Timeouts
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
        
        # Buffer settings
        proxy_buffering on;
        proxy_buffer_size 4k;
        proxy_buffers 8 4k;
    }
    
    # Authentication endpoints (stricter rate limiting)
    location /api/auth/ {
        limit_req zone=auth burst=5 nodelay;
        
        proxy_pass http://127.0.0.1:8000;
        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;
    }
    
    # Health check endpoint
    location /health {
        access_log off;
        return 200 "healthy\n";
        add_header Content-Type text/plain;
    }
}

Enable Nginx Configuration

# Enable site
sudo ln -s /etc/nginx/sites-available/aimod /etc/nginx/sites-enabled/

# Remove default site
sudo rm /etc/nginx/sites-enabled/default

# Test configuration
sudo nginx -t

# Restart Nginx
sudo systemctl restart nginx
sudo systemctl enable nginx

8. SSL Certificate Setup

# Obtain SSL certificate
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

# Test automatic renewal
sudo certbot renew --dry-run

# Set up automatic renewal
echo "0 12 * * * /usr/bin/certbot renew --quiet" | sudo crontab -

9. Firewall Configuration

# Install UFW
sudo apt install -y ufw

# Default policies
sudo ufw default deny incoming
sudo ufw default allow outgoing

# Allow SSH
sudo ufw allow ssh

# Allow HTTP and HTTPS
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# Allow PostgreSQL (local only)
sudo ufw allow from 127.0.0.1 to any port 5432

# Allow Redis (local only)
sudo ufw allow from 127.0.0.1 to any port 6379

# Enable firewall
sudo ufw enable

# Check status
sudo ufw status verbose

📊 Monitoring and Logging

Log Management

Centralized Logging

# Configure rsyslog for application logs
sudo nano /etc/rsyslog.d/50-aimod.conf
# AIMod application logs
:programname, isequal, "aimod-bot" /var/log/aimod/bot.log
:programname, isequal, "aimod-backend" /var/log/aimod/backend.log
& stop

Log Rotation

# Create log rotation configuration
sudo nano /etc/logrotate.d/aimod
/var/log/aimod/*.log {
    daily
    missingok
    rotate 30
    compress
    delaycompress
    notifempty
    create 644 aimod aimod
    postrotate
        systemctl reload rsyslog
    endscript
}

Performance Monitoring

System Monitoring Script

# Create monitoring script
nano /home/aimod/monitor.sh
#!/bin/bash

# System metrics
echo "=== System Metrics $(date) ==="
echo "CPU Usage: $(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1)"
echo "Memory Usage: $(free | grep Mem | awk '{printf "%.2f%%", $3/$2 * 100.0}')"
echo "Disk Usage: $(df -h / | awk 'NR==2{printf "%s", $5}')"

# Service status
echo "=== Service Status ==="
systemctl is-active aimod-bot.service
systemctl is-active aimod-backend.service
systemctl is-active postgresql.service
systemctl is-active redis.service
systemctl is-active nginx.service

# Database connections
echo "=== Database Connections ==="
sudo -u postgres psql -d aimod_bot_prod -c "SELECT count(*) FROM pg_stat_activity;"

# Log recent errors
echo "=== Recent Errors ==="
journalctl -u aimod-bot.service --since "1 hour ago" | grep -i error | tail -5
# Make executable
chmod +x /home/aimod/monitor.sh

# Add to crontab for regular monitoring
echo "*/15 * * * * /home/aimod/monitor.sh >> /var/log/aimod/monitor.log 2>&1" | crontab -

🔒 Security Hardening

System Security

# Disable root login
sudo nano /etc/ssh/sshd_config
# Set: PermitRootLogin no

# Configure fail2ban
sudo apt install -y fail2ban
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

# Create custom jail for Nginx
sudo nano /etc/fail2ban/jail.d/nginx.conf
[nginx-http-auth]
enabled = true
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 3
bantime = 3600

[nginx-limit-req]
enabled = true
filter = nginx-limit-req
logpath = /var/log/nginx/error.log
maxretry = 10
bantime = 600

Application Security

# Set proper file permissions
sudo chown -R aimod:aimod /home/aimod/aimod
sudo chmod 600 /home/aimod/aimod/.env.production
sudo chmod -R 755 /home/aimod/aimod
sudo chmod +x /home/aimod/aimod/bot.py

🔄 Backup Strategy

Database Backup

# Create backup script
nano /home/aimod/backup.sh
#!/bin/bash

BACKUP_DIR="/home/aimod/backups"
DATE=$(date +%Y%m%d_%H%M%S)
DB_NAME="aimod_bot_prod"

# Create backup directory
mkdir -p $BACKUP_DIR

# Database backup
pg_dump -h localhost -U aimod_user $DB_NAME | gzip > $BACKUP_DIR/db_backup_$DATE.sql.gz

# Application backup
tar -czf $BACKUP_DIR/app_backup_$DATE.tar.gz -C /home/aimod aimod --exclude=aimod/venv --exclude=aimod/.git

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

echo "Backup completed: $DATE"
# Make executable and schedule
chmod +x /home/aimod/backup.sh
echo "0 2 * * * /home/aimod/backup.sh >> /var/log/aimod/backup.log 2>&1" | crontab -

Next: Database Migration - Migrating from JSON to PostgreSQL