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

604 lines
13 KiB
Markdown

# Production Deployment Guide
This guide walks you through deploying the Faction War Dispatch Bot to a production server.
## Table of Contents
1. [Security Considerations](#security-considerations)
2. [Server Requirements](#server-requirements)
3. [Installation Steps](#installation-steps)
4. [SSL/HTTPS Setup](#sslhttps-setup)
5. [Free Domain Setup](#free-domain-setup)
6. [Systemd Service Setup](#systemd-service-setup)
7. [Firewall Configuration](#firewall-configuration)
8. [Monitoring & Maintenance](#monitoring--maintenance)
---
## Security Considerations
### Critical Security Steps (DO BEFORE DEPLOYMENT!)
1. **Change Default Secrets**
```bash
# 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](#sslhttps-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](#firewall-configuration) below
5. **Keep Dependencies Updated**
```bash
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
```bash
# 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
```bash
# 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
```bash
# Create .env file from example
cp .env.example .env
# Edit .env with your actual values
nano .env
```
**Important .env values to set:**
```bash
# 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
```bash
# 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
### Option 1: Using Let's Encrypt (Recommended - Free SSL)
```bash
# 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)
```bash
# 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
```bash
# 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:
```bash
sudo nano /etc/nginx/sites-available/faction-war
```
**Configuration file:**
```nginx
# 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:**
```bash
# 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:
```bash
sudo nano /etc/systemd/system/faction-war.service
```
**Service file:**
```ini
[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:**
```bash
# 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)
```bash
# 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
```bash
# 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
```bash
# 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
```bash
# Create backup script
sudo nano /opt/faction-war/backup.sh
```
**Backup script:**
```bash
#!/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"
```
```bash
# 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
```bash
# 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
```bash
# 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
```bash
# 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
```bash
# Renew certificate manually
sudo certbot renew
# Test auto-renewal
sudo certbot renew --dry-run
```
### Permission Issues
```bash
# 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`:
```ini
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:
```bash
sudo apt install redis-server -y
pip install redis
```
---
## Quick Start Summary
```bash
# 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`