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