Files
faction_war_dispatch_bot/DEPLOYMENT.md
2026-01-28 08:53:21 -05:00

13 KiB

Production Deployment Guide

This guide walks you through deploying the Faction War Dispatch Bot to a production server.

Table of Contents

  1. Security Considerations
  2. Server Requirements
  3. Installation Steps
  4. SSL/HTTPS Setup
  5. Free Domain Setup
  6. Systemd Service Setup
  7. Firewall Configuration
  8. Monitoring & Maintenance

Security Considerations

Critical Security Steps (DO BEFORE DEPLOYMENT!)

  1. Change Default Secrets

    # Generate a strong random password
    openssl rand -base64 32
    
    # Generate a strong JWT secret
    openssl rand -hex 64
    
  2. Never Commit Secrets to Git

    • Use .env file for secrets (already in .gitignore)
    • Or use the Settings page to configure via web UI
    • Keep data/config.json out of version control (already in .gitignore)
  3. HTTPS is REQUIRED

    • JWT tokens and passwords are transmitted over the network
    • Without HTTPS, credentials can be intercepted
    • See SSL/HTTPS Setup below
  4. Firewall Configuration

    • Only expose port 443 (HTTPS) or 80 (HTTP - redirects to HTTPS)
    • Block port 8000 from external access (use reverse proxy)
    • See Firewall Configuration below
  5. Keep Dependencies Updated

    pip install --upgrade -r requirements.txt
    
  6. Backup Your Data

    • Backup the data/ directory regularly
    • Contains group assignments, Discord mappings, and config

Server Requirements

Minimum Specs

  • OS: Ubuntu 20.04+ / Debian 11+ (or any Linux distribution)
  • RAM: 512MB minimum, 1GB recommended
  • CPU: 1 core minimum
  • Storage: 5GB minimum
  • Network: Static IP or dynamic DNS

Required Software

  • Python 3.11+
  • Nginx (reverse proxy)
  • Certbot (for SSL certificates)
  • systemd (process management)

Installation Steps

1. Initial Server Setup

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

# Install required packages
sudo apt install -y python3 python3-pip python3-venv nginx certbot python3-certbot-nginx git

# Create a non-root user for the application (recommended)
sudo adduser --system --group --home /opt/faction-war factionwar

2. Clone and Setup Application

# Switch to the application user
sudo su - factionwar

# Clone the repository (or upload files via SCP/SFTP)
cd /opt/faction-war
git clone <your-repo-url> app
cd app

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

# Install dependencies
pip install -r requirements.txt

3. Configure Environment Variables

# Create .env file from example
cp .env.example .env

# Edit .env with your actual values
nano .env

Important .env values to set:

# Generate strong random values for these:
AUTH_PASSWORD=<generate-with: openssl rand -base64 32>
JWT_SECRET=<generate-with: openssl rand -hex 64>

# Add your API keys:
TORN_API_KEY=<your-torn-api-key>
FFSCOUTER_KEY=<your-ffscouter-key>
DISCORD_TOKEN=<your-discord-bot-token>
ALLOWED_CHANNEL_ID=<your-discord-channel-id>

4. Create Data Directory

# Create data directory for persistent storage
mkdir -p /opt/faction-war/app/data
chown -R factionwar:factionwar /opt/faction-war/app/data
chmod 700 /opt/faction-war/app/data  # Restrict access to sensitive data

SSL/HTTPS Setup

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

# Get SSL certificate (replace with your domain)
sudo certbot --nginx -d yourdomain.com

# Certbot will automatically configure Nginx for HTTPS
# Follow the prompts to set up automatic renewal

Option 2: Self-Signed Certificate (Development Only)

# Generate self-signed certificate (NOT for production)
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout /etc/ssl/private/nginx-selfsigned.key \
  -out /etc/ssl/certs/nginx-selfsigned.crt

Free Domain Setup

Option 1: Free Subdomain Services

  1. DuckDNS (https://www.duckdns.org)

    • Completely free
    • Provides yourdomain.duckdns.org
    • Supports dynamic DNS updates
    # Install DuckDNS updater
    mkdir -p /opt/duckdns
    cd /opt/duckdns
    echo "echo url=\"https://www.duckdns.org/update?domains=YOURDOMAIN&token=YOUR-TOKEN&ip=\" | curl -k -o ~/duckdns/duck.log -K -" > duck.sh
    chmod 700 duck.sh
    
    # Add to crontab for auto-updates
    crontab -e
    # Add: */5 * * * * /opt/duckdns/duck.sh >/dev/null 2>&1
    
  2. FreeDNS (https://freedns.afraid.org)

    • Free subdomain or use their domains
    • More domain options than DuckDNS
  3. No-IP (https://www.noip.com)

    • Free tier available
    • Dynamic DNS client included

Option 2: Cloudflare (Free Tier)

If you own a domain:

  1. Transfer DNS to Cloudflare (free)
  2. Get free SSL certificate
  3. DDoS protection included
  4. CDN included

Nginx Reverse Proxy Configuration

Create Nginx configuration:

sudo nano /etc/nginx/sites-available/faction-war

Configuration file:

# HTTP - Redirect to HTTPS
server {
    listen 80;
    listen [::]:80;
    server_name yourdomain.com;  # Replace with your domain

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

# HTTPS - Main Application
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name yourdomain.com;  # Replace with your domain

    # SSL Configuration (managed by Certbot)
    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

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

    # Logging
    access_log /var/log/nginx/faction-war-access.log;
    error_log /var/log/nginx/faction-war-error.log;

    # Proxy settings
    location / {
        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;

        # WebSocket support (if needed in future)
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        # Timeouts
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }

    # Static files (optional optimization)
    location /static/ {
        alias /opt/faction-war/app/static/;
        expires 1d;
        add_header Cache-Control "public, immutable";
    }
}

Enable the site:

# Create symbolic link
sudo ln -s /etc/nginx/sites-available/faction-war /etc/nginx/sites-enabled/

# Test configuration
sudo nginx -t

# Reload Nginx
sudo systemctl reload nginx

Systemd Service Setup

Create a systemd service to run the bot automatically:

sudo nano /etc/systemd/system/faction-war.service

Service file:

[Unit]
Description=Faction War Dispatch Bot
After=network.target

[Service]
Type=simple
User=factionwar
Group=factionwar
WorkingDirectory=/opt/faction-war/app
Environment="PATH=/opt/faction-war/app/venv/bin"
ExecStart=/opt/faction-war/app/venv/bin/python main.py

# Restart policy
Restart=always
RestartSec=10

# Security hardening
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/faction-war/app/data

# Logging
StandardOutput=journal
StandardError=journal
SyslogIdentifier=faction-war

[Install]
WantedBy=multi-user.target

Enable and start the service:

# Reload systemd
sudo systemctl daemon-reload

# Enable service to start on boot
sudo systemctl enable faction-war

# Start the service
sudo systemctl start faction-war

# Check status
sudo systemctl status faction-war

# View logs
sudo journalctl -u faction-war -f

Firewall Configuration

Using UFW (Ubuntu/Debian)

# Install UFW
sudo apt install ufw -y

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

# Allow SSH (IMPORTANT - don't lock yourself out!)
sudo ufw allow ssh

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

# Enable firewall
sudo ufw enable

# Check status
sudo ufw status verbose

Important: Do NOT allow port 8000 externally. The application runs on port 8000 internally, but should only be accessible via Nginx reverse proxy on ports 80/443.


Monitoring & Maintenance

Log Files

# Application logs
sudo journalctl -u faction-war -f

# Nginx access logs
sudo tail -f /var/log/nginx/faction-war-access.log

# Nginx error logs
sudo tail -f /var/log/nginx/faction-war-error.log

Health Checks

# Check if service is running
sudo systemctl status faction-war

# Check if Nginx is running
sudo systemctl status nginx

# Test application response
curl -I https://yourdomain.com

Backup Strategy

# Create backup script
sudo nano /opt/faction-war/backup.sh

Backup script:

#!/bin/bash
BACKUP_DIR="/opt/faction-war/backups"
DATE=$(date +%Y%m%d_%H%M%S)
APP_DIR="/opt/faction-war/app"

mkdir -p $BACKUP_DIR

# Backup data directory
tar -czf $BACKUP_DIR/data_backup_$DATE.tar.gz -C $APP_DIR data/

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

echo "Backup completed: data_backup_$DATE.tar.gz"
# Make executable
sudo chmod +x /opt/faction-war/backup.sh

# Add to cron for daily backups
sudo crontab -e
# Add: 0 2 * * * /opt/faction-war/backup.sh

Updates

# Stop the service
sudo systemctl stop faction-war

# Update code
cd /opt/faction-war/app
sudo -u factionwar git pull

# Update dependencies
sudo -u factionwar /opt/faction-war/app/venv/bin/pip install --upgrade -r requirements.txt

# Restart service
sudo systemctl start faction-war

# Check status
sudo systemctl status faction-war

Troubleshooting

Service Won't Start

# Check logs for errors
sudo journalctl -u faction-war -n 50 --no-pager

# Check Python errors
sudo -u factionwar /opt/faction-war/app/venv/bin/python /opt/faction-war/app/main.py

Nginx 502 Bad Gateway

# Check if application is running
sudo systemctl status faction-war

# Check if application is listening on port 8000
sudo netstat -tlnp | grep 8000

# Check Nginx error logs
sudo tail -f /var/log/nginx/faction-war-error.log

SSL Certificate Issues

# Renew certificate manually
sudo certbot renew

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

Permission Issues

# Fix data directory permissions
sudo chown -R factionwar:factionwar /opt/faction-war/app/data
sudo chmod 700 /opt/faction-war/app/data

Security Checklist

Before going live, verify:

  • Strong AUTH_PASSWORD set in .env or Settings page
  • Strong JWT_SECRET set in .env or Settings page
  • SSL certificate installed and working (HTTPS)
  • Firewall configured (only ports 22, 80, 443 open)
  • Port 8000 NOT accessible from outside
  • .env file has restricted permissions (chmod 600)
  • data/ directory has restricted permissions (chmod 700)
  • Automatic SSL renewal configured
  • Backup script configured and tested
  • Monitoring/logging configured
  • Git repository does NOT contain secrets
  • Default passwords changed

Performance Tuning (Optional)

Uvicorn with Multiple Workers

Edit /etc/systemd/system/faction-war.service:

ExecStart=/opt/faction-war/app/venv/bin/uvicorn main:app --host 127.0.0.1 --port 8000 --workers 2

Redis for Session Storage (Future Enhancement)

For better session management across multiple workers, consider adding Redis:

sudo apt install redis-server -y
pip install redis

Quick Start Summary

# 1. Server setup
sudo apt update && sudo apt install -y python3 python3-venv nginx certbot python3-certbot-nginx

# 2. Clone and install
cd /opt && sudo mkdir faction-war && cd faction-war
git clone <repo> app && cd app
python3 -m venv venv && source venv/bin/activate
pip install -r requirements.txt

# 3. Configure
cp .env.example .env
nano .env  # Set your secrets and API keys

# 4. Setup SSL
sudo certbot --nginx -d yourdomain.com

# 5. Configure Nginx (use config from above)
sudo nano /etc/nginx/sites-available/faction-war
sudo ln -s /etc/nginx/sites-available/faction-war /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

# 6. Setup systemd service (use config from above)
sudo nano /etc/systemd/system/faction-war.service
sudo systemctl daemon-reload
sudo systemctl enable faction-war
sudo systemctl start faction-war

# 7. Configure firewall
sudo ufw allow ssh && sudo ufw allow 80/tcp && sudo ufw allow 443/tcp
sudo ufw enable

# 8. Done! Visit https://yourdomain.com

Getting Help

If you encounter issues:

  1. Check logs: sudo journalctl -u faction-war -f
  2. Check Nginx logs: sudo tail -f /var/log/nginx/faction-war-error.log
  3. Test the application directly: curl http://127.0.0.1:8000
  4. Verify firewall: sudo ufw status
  5. Test SSL: curl -I https://yourdomain.com