Files
firefrost-operations-manual/docs/tasks/_archive/whitelist-manager/deployment-plan.md
Claude dca114eee9 chore: Task cleanup - archive 3, delete 11 obsolete folders
Archive threshold: ≥50KB OR ≥4 files

Archived to _archive/:
- firefrost-codex-migration-to-open-webui (127K, 9 files)
- whitelist-manager (65K, 5 files)
- self-hosted-ai-stack-on-tx1 (35K, 4 files)

Deleted (obsolete/superseded):
- builder-rank-holly-setup
- consultant-photo-processing
- ghost-theme-migration (empty)
- gitea-plane-integration (Plane abandoned)
- gitea-upgrade (Kanban approach abandoned)
- plane-deployment (superseded by decommission)
- pterodactyl-blueprint-asset-build (fold into #26)
- pterodactyl-modpack-version-display (fold into #26)
- scope-document-corrections (too vague)
- scoped-gitea-token (honor system working)
- whitelist-manager-v1-12-compatibility (rolled into Trinity Console)

Also added: Gemini task management consolidation consultation

Chronicler #69
2026-04-08 14:17:26 +00:00

29 KiB

Whitelist Manager Web Dashboard - Deployment Plan

Document Status: ACTIVE DEPLOYMENT PLAN
Created: February 16, 2026
Created By: The Chronicler (current session)
Priority: Tier 0 - Immediate Win
Estimated Time: 2-2.5 hours
Scope: Build web dashboard for managing Minecraft server whitelists across 11 servers


📊 PROJECT OVERVIEW

Purpose

Create a web-based dashboard to manage player whitelists across all 11 Minecraft servers, replacing manual SSH and Pterodactyl console work.

Current Pain Points

  • Manual SSH to each node (TX1, NC1)
  • Update whitelist on each of 12+ servers individually via Pterodactyl console
  • Time-consuming (15+ minutes per whitelist change)
  • Error-prone (easy to miss a server)
  • No visibility into current whitelist status across all servers

Solution

Centralized web dashboard at https://whitelist.firefrostgaming.com that:

  • Shows all 11 Minecraft servers with whitelist status (ON/OFF)
  • Toggle whitelist enforcement with one click per server
  • Add player to all servers at once
  • Remove player from all servers at once
  • View current whitelist for each server
  • Accessible to authorized staff only

Success Metrics

  • 15-minute task → 30 seconds
  • Zero-error whitelist management
  • Full visibility across all servers
  • Staff can manage without SSH access

🎯 SCOPE

In Scope (MVP)

  • Web dashboard with server list and status
  • Toggle whitelist ON/OFF per server
  • Add player to one or all servers
  • Remove player from one or all servers
  • View current whitelist
  • Basic authentication (username/password)
  • SSL/HTTPS access
  • Responsive design (works on mobile)

Out of Scope (Future Enhancements)

  • Discord bot integration
  • Paymenter subscriber auto-whitelist
  • Whitelist sync verification
  • Player activity tracking
  • Automated whitelist backup
  • Multi-user role permissions
  • SSO integration with Wiki.js

Server Coverage

Managed (11 Minecraft servers):

  1. Reclamation - TX (1eb33479-a6bc-4e8f-b64d-d1e4bfa0a8b4)
  2. The Ember Project - NC (124f9060-58a7-457a-b2cf-b4024fce2951)
  3. Stoneblock 4 - TX (a0efbfe8-4b97-4a90-869d-ffe6d3072bd5)
  4. Minecolonies: Create and Conquer - NC (a14201d2-83b2-44e6-ae48-e6c4cbc56f24)
  5. Society: Sunlit Valley - TX (9310d0a6-62a6-4fe6-82c4-eb483dc68876)
  6. All The Mods 10 - NC (82e63949-8fbf-4a44-b32a-53324e8492bf)
  7. Vanilla 1.21.11 - TX (3bed1bda-f648-4630-801a-fe9f2e3d3f27)
  8. Homestead - NC (2f85d4ef-aa49-4dd6-b448-beb3fca1db12)
  9. All The Mons - TX (668a5220-7e72-4379-9165-bdbb84bc9806)
  10. EMC Subterra Tech - NC (09a95f38-9f8c-404a-9557-3a7c44258223)

Excluded (Non-Minecraft):

  • FoundryVTT - TX (7d8f15a0-4ee7-4dd6-85dc-ab42966f733d) - Not Minecraft
  • Hytale - NC (13c80cb8-f6f8-4bfe-9cdb-823d7e951584) - Not Minecraft

🏗️ ARCHITECTURE

Technology Stack

  • Backend: Python 3 + Flask (lightweight web framework)
  • Frontend: HTML5 + TailwindCSS (responsive design)
  • API: Pterodactyl API v1 (websocket for console commands)
  • Web Server: Nginx (reverse proxy)
  • SSL: Let's Encrypt (automatic renewal)
  • Process Manager: systemd (auto-restart on failure)
  • Authentication: Flask-HTTPAuth (basic auth)

Infrastructure

  • Host: Ghost VPS (Chicago IL) - same server as Wiki.js Staff
  • Domain: whitelist.firefrostgaming.com
  • Port: 5001 (internal), 443 (external via Nginx)
  • Directory: /opt/firefrost/whitelist-manager/

File Structure

/opt/firefrost/whitelist-manager/
├── app.py                      # Flask application (main)
├── config.json                 # Server list + settings
├── requirements.txt            # Python dependencies
├── .env                        # Secrets (API key, auth credentials)
├── templates/
│   └── dashboard.html          # Web interface
├── static/
│   ├── css/
│   │   └── styles.css          # Custom styling
│   └── js/
│       └── dashboard.js        # Frontend logic
└── logs/
    └── whitelist-manager.log   # Application logs

Data Flow

User Browser (HTTPS)
    ↓
Nginx (reverse proxy, SSL termination)
    ↓
Flask App (port 5001)
    ↓
Pterodactyl API (console commands)
    ↓
Minecraft Server (whitelist.json updated)

📝 PHASE 1: INFORMATION GATHERING

Time Estimate: 5 minutes

Requirements Checklist

1. Pterodactyl Access

  • Pterodactyl panel URL: ________________________
  • API key generated (Account → API Credentials)
  • API key permissions verified (can send console commands)
  • Test API key with one server

2. Ghost VPS Access

  • SSH credentials obtained
  • Root access verified
  • Nginx installed and running
  • Python 3.9+ installed
  • Port 5001 available

3. Whitelist Method Determine how whitelist enforcement works on Minecraft servers:

  • Option A: Console command (/whitelist on, /whitelist off)
  • Option B: server.properties file (white-list=true/false + restart)
  • Option C: Pterodactyl startup variable

Recommended: Option A (console commands) - no restart required

4. Authentication

  • Admin username chosen: ________________________
  • Admin password chosen: ________________________
  • Additional staff users (if needed): ________________________

5. DNS Configuration

  • DNS provider access (Cloudflare/other)
  • Create A record: whitelist.firefrostgaming.com → Ghost VPS IP
  • TTL set to 300 (5 minutes for testing)

📝 PHASE 2: DNS & INFRASTRUCTURE SETUP

Time Estimate: 15 minutes

Step 1: DNS Configuration

# Create DNS A Record
# Domain: whitelist.firefrostgaming.com
# Type: A
# Value: [Ghost VPS IP Address]
# TTL: 300
# Proxy: Off (for initial setup)

Verification:

# Wait 5 minutes, then test:
nslookup whitelist.firefrostgaming.com
# Should return Ghost VPS IP

Step 2: SSH into Ghost VPS

ssh root@[ghost-vps-ip]

Step 3: Create Application Directory

# Create directory structure
mkdir -p /opt/firefrost/whitelist-manager/{templates,static/css,static/js,logs}
cd /opt/firefrost/whitelist-manager

# Set permissions
chown -R www-data:www-data /opt/firefrost/whitelist-manager
chmod -R 755 /opt/firefrost/whitelist-manager

Step 4: Install Python Dependencies

# Update system
apt update
apt install -y python3 python3-pip python3-venv

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

# Install Flask and dependencies
pip install flask flask-cors flask-httpauth python-dotenv requests websocket-client
pip freeze > requirements.txt

Step 5: Verify Nginx Installed

# Check Nginx status
systemctl status nginx

# If not installed:
apt install -y nginx certbot python3-certbot-nginx

📝 PHASE 3: BUILD THE APPLICATION

Time Estimate: 45-60 minutes

Step 1: Create Server Configuration

File: /opt/firefrost/whitelist-manager/config.json

{
  "pterodactyl": {
    "panel_url": "https://panel.firefrostgaming.com",
    "api_key": "PLACEHOLDER_WILL_BE_IN_ENV_FILE"
  },
  "servers": [
    {
      "id": "1",
      "name": "Reclamation - TX",
      "uuid": "1eb33479-a6bc-4e8f-b64d-d1e4bfa0a8b4",
      "node": "TX1",
      "enabled": true
    },
    {
      "id": "2",
      "name": "The Ember Project - NC",
      "uuid": "124f9060-58a7-457a-b2cf-b4024fce2951",
      "node": "NC1",
      "enabled": true
    },
    {
      "id": "3",
      "name": "Stoneblock 4 - TX",
      "uuid": "a0efbfe8-4b97-4a90-869d-ffe6d3072bd5",
      "node": "TX1",
      "enabled": true
    },
    {
      "id": "4",
      "name": "Minecolonies: Create and Conquer - NC",
      "uuid": "a14201d2-83b2-44e6-ae48-e6c4cbc56f24",
      "node": "NC1",
      "enabled": true
    },
    {
      "id": "5",
      "name": "Society: Sunlit Valley - TX",
      "uuid": "9310d0a6-62a6-4fe6-82c4-eb483dc68876",
      "node": "TX1",
      "enabled": true
    },
    {
      "id": "6",
      "name": "All The Mods 10 - NC",
      "uuid": "82e63949-8fbf-4a44-b32a-53324e8492bf",
      "node": "NC1",
      "enabled": true
    },
    {
      "id": "7",
      "name": "Vanilla 1.21.11 - TX",
      "uuid": "3bed1bda-f648-4630-801a-fe9f2e3d3f27",
      "node": "TX1",
      "enabled": true
    },
    {
      "id": "8",
      "name": "Homestead - NC",
      "uuid": "2f85d4ef-aa49-4dd6-b448-beb3fca1db12",
      "node": "NC1",
      "enabled": true
    },
    {
      "id": "9",
      "name": "All The Mons - TX",
      "uuid": "668a5220-7e72-4379-9165-bdbb84bc9806",
      "node": "TX1",
      "enabled": true
    },
    {
      "id": "10",
      "name": "EMC Subterra Tech - NC",
      "uuid": "09a95f38-9f8c-404a-9557-3a7c44258223",
      "node": "NC1",
      "enabled": true
    }
  ],
  "settings": {
    "log_level": "INFO",
    "log_file": "/opt/firefrost/whitelist-manager/logs/whitelist-manager.log",
    "api_timeout": 30,
    "console_command_delay": 1
  }
}

Step 2: Create Environment File

File: /opt/firefrost/whitelist-manager/.env

# Pterodactyl API
PTERODACTYL_API_KEY=ptlc_YOUR_API_KEY_HERE

# Flask Configuration
FLASK_SECRET_KEY=GENERATE_RANDOM_STRING_HERE
FLASK_ENV=production

# Basic Auth
ADMIN_USERNAME=admin
ADMIN_PASSWORD=SECURE_PASSWORD_HERE

# Application
HOST=127.0.0.1
PORT=5001
DEBUG=False

Security:

chmod 600 /opt/firefrost/whitelist-manager/.env
chown www-data:www-data /opt/firefrost/whitelist-manager/.env

Step 3: Create Flask Application

File: /opt/firefrost/whitelist-manager/app.py

#!/usr/bin/env python3
"""
Firefrost Gaming - Whitelist Manager
Web dashboard for managing Minecraft server whitelists via Pterodactyl API
"""

import os
import json
import logging
from datetime import datetime
from flask import Flask, render_template, request, jsonify
from flask_httpauth import HTTPBasicAuth
from dotenv import load_dotenv
import requests

# Load environment variables
load_dotenv()

# Initialize Flask app
app = Flask(__name__)
app.config['SECRET_KEY'] = os.getenv('FLASK_SECRET_KEY')
auth = HTTPBasicAuth()

# Load configuration
with open('config.json', 'r') as f:
    config = json.load(f)

# Setup logging
logging.basicConfig(
    level=getattr(logging, config['settings']['log_level']),
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler(config['settings']['log_file']),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger(__name__)

# Pterodactyl API Configuration
PANEL_URL = config['pterodactyl']['panel_url']
API_KEY = os.getenv('PTERODACTYL_API_KEY')
HEADERS = {
    'Authorization': f'Bearer {API_KEY}',
    'Content-Type': 'application/json',
    'Accept': 'Application/vnd.pterodactyl.v1+json'
}

# Authentication
@auth.verify_password
def verify_password(username, password):
    """Verify basic auth credentials"""
    admin_user = os.getenv('ADMIN_USERNAME')
    admin_pass = os.getenv('ADMIN_PASSWORD')
    if username == admin_user and password == admin_pass:
        return username
    return None

# Routes
@app.route('/')
@auth.login_required
def index():
    """Main dashboard"""
    return render_template('dashboard.html', servers=config['servers'])

@app.route('/api/servers', methods=['GET'])
@auth.login_required
def get_servers():
    """Get all server configurations"""
    return jsonify(config['servers'])

@app.route('/api/server/<uuid>/whitelist/status', methods=['GET'])
@auth.login_required
def get_whitelist_status(uuid):
    """Get whitelist status for a specific server"""
    try:
        # Send console command to check whitelist status
        response = send_console_command(uuid, '/whitelist list')
        
        # Parse response to determine if whitelist is enabled
        # This is simplified - actual implementation needs websocket
        return jsonify({
            'uuid': uuid,
            'enabled': True,  # Placeholder
            'players': []  # Placeholder
        })
    except Exception as e:
        logger.error(f"Error getting whitelist status for {uuid}: {str(e)}")
        return jsonify({'error': str(e)}), 500

@app.route('/api/server/<uuid>/whitelist/toggle', methods=['POST'])
@auth.login_required
def toggle_whitelist(uuid):
    """Toggle whitelist on/off for a specific server"""
    try:
        data = request.get_json()
        enabled = data.get('enabled', False)
        
        command = '/whitelist on' if enabled else '/whitelist off'
        response = send_console_command(uuid, command)
        
        logger.info(f"Whitelist {'enabled' if enabled else 'disabled'} for {uuid}")
        return jsonify({'success': True, 'enabled': enabled})
    except Exception as e:
        logger.error(f"Error toggling whitelist for {uuid}: {str(e)}")
        return jsonify({'error': str(e)}), 500

@app.route('/api/server/<uuid>/whitelist/add', methods=['POST'])
@auth.login_required
def add_to_whitelist(uuid):
    """Add player to whitelist"""
    try:
        data = request.get_json()
        player = data.get('player')
        
        if not player:
            return jsonify({'error': 'Player name required'}), 400
        
        command = f'/whitelist add {player}'
        response = send_console_command(uuid, command)
        
        logger.info(f"Added {player} to whitelist on {uuid}")
        return jsonify({'success': True, 'player': player})
    except Exception as e:
        logger.error(f"Error adding player to {uuid}: {str(e)}")
        return jsonify({'error': str(e)}), 500

@app.route('/api/server/<uuid>/whitelist/remove', methods=['POST'])
@auth.login_required
def remove_from_whitelist(uuid):
    """Remove player from whitelist"""
    try:
        data = request.get_json()
        player = data.get('player')
        
        if not player:
            return jsonify({'error': 'Player name required'}), 400
        
        command = f'/whitelist remove {player}'
        response = send_console_command(uuid, command)
        
        logger.info(f"Removed {player} from whitelist on {uuid}")
        return jsonify({'success': True, 'player': player})
    except Exception as e:
        logger.error(f"Error removing player from {uuid}: {str(e)}")
        return jsonify({'error': str(e)}), 500

@app.route('/api/whitelist/add-all', methods=['POST'])
@auth.login_required
def add_to_all_whitelists():
    """Add player to all server whitelists"""
    try:
        data = request.get_json()
        player = data.get('player')
        
        if not player:
            return jsonify({'error': 'Player name required'}), 400
        
        results = []
        for server in config['servers']:
            if server['enabled']:
                try:
                    command = f'/whitelist add {player}'
                    send_console_command(server['uuid'], command)
                    results.append({'uuid': server['uuid'], 'success': True})
                    logger.info(f"Added {player} to {server['name']}")
                except Exception as e:
                    results.append({'uuid': server['uuid'], 'success': False, 'error': str(e)})
                    logger.error(f"Failed to add {player} to {server['name']}: {str(e)}")
        
        return jsonify({'player': player, 'results': results})
    except Exception as e:
        logger.error(f"Error adding player to all servers: {str(e)}")
        return jsonify({'error': str(e)}), 500

@app.route('/api/whitelist/remove-all', methods=['POST'])
@auth.login_required
def remove_from_all_whitelists():
    """Remove player from all server whitelists"""
    try:
        data = request.get_json()
        player = data.get('player')
        
        if not player:
            return jsonify({'error': 'Player name required'}), 400
        
        results = []
        for server in config['servers']:
            if server['enabled']:
                try:
                    command = f'/whitelist remove {player}'
                    send_console_command(server['uuid'], command)
                    results.append({'uuid': server['uuid'], 'success': True})
                    logger.info(f"Removed {player} from {server['name']}")
                except Exception as e:
                    results.append({'uuid': server['uuid'], 'success': False, 'error': str(e)})
                    logger.error(f"Failed to remove {player} from {server['name']}: {str(e)}")
        
        return jsonify({'player': player, 'results': results})
    except Exception as e:
        logger.error(f"Error removing player from all servers: {str(e)}")
        return jsonify({'error': str(e)}), 500

def send_console_command(server_uuid, command):
    """
    Send console command to Pterodactyl server
    
    Note: This is a simplified version. Production should use websocket
    for real-time command execution and response monitoring.
    """
    url = f"{PANEL_URL}/api/client/servers/{server_uuid}/command"
    payload = {'command': command}
    
    response = requests.post(url, headers=HEADERS, json=payload, timeout=config['settings']['api_timeout'])
    response.raise_for_status()
    
    return response.json()

if __name__ == '__main__':
    host = os.getenv('HOST', '127.0.0.1')
    port = int(os.getenv('PORT', 5001))
    debug = os.getenv('DEBUG', 'False').lower() == 'true'
    
    logger.info(f"Starting Whitelist Manager on {host}:{port}")
    app.run(host=host, port=port, debug=debug)

Step 4: Create HTML Dashboard

File: /opt/firefrost/whitelist-manager/templates/dashboard.html

(HTML template would go here - full responsive dashboard with TailwindCSS)

Step 5: Create JavaScript

File: /opt/firefrost/whitelist-manager/static/js/dashboard.js

(JavaScript for API calls and UI updates would go here)


📝 PHASE 4: SECURITY & WEB SERVER

Time Estimate: 20 minutes

Step 1: Create systemd Service

File: /etc/systemd/system/whitelist-manager.service

[Unit]
Description=Firefrost Gaming Whitelist Manager
After=network.target

[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/opt/firefrost/whitelist-manager
Environment="PATH=/opt/firefrost/whitelist-manager/venv/bin"
ExecStart=/opt/firefrost/whitelist-manager/venv/bin/python app.py
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

Enable and start:

systemctl daemon-reload
systemctl enable whitelist-manager
systemctl start whitelist-manager
systemctl status whitelist-manager

Step 2: Configure Nginx Reverse Proxy

File: /etc/nginx/sites-available/whitelist.firefrostgaming.com

server {
    listen 80;
    server_name whitelist.firefrostgaming.com;
    
    location / {
        return 301 https://$server_name$request_uri;
    }
}

server {
    listen 443 ssl http2;
    server_name whitelist.firefrostgaming.com;
    
    # SSL certificates (will be created by certbot)
    ssl_certificate /etc/letsencrypt/live/whitelist.firefrostgaming.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/whitelist.firefrostgaming.com/privkey.pem;
    
    # SSL configuration
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    
    # Logging
    access_log /var/log/nginx/whitelist.firefrostgaming.com.access.log;
    error_log /var/log/nginx/whitelist.firefrostgaming.com.error.log;
    
    # Reverse proxy to Flask app
    location / {
        proxy_pass http://127.0.0.1:5001;
        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;
    }
}

Enable site:

ln -s /etc/nginx/sites-available/whitelist.firefrostgaming.com /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginx

Step 3: Generate SSL Certificate

certbot --nginx -d whitelist.firefrostgaming.com

📝 PHASE 5: TESTING

Time Estimate: 15 minutes

Test Plan

Test 1: Application Health

# Check service running
systemctl status whitelist-manager

# Check logs
tail -f /opt/firefrost/whitelist-manager/logs/whitelist-manager.log

# Test local access
curl http://127.0.0.1:5001

Test 2: Web Access

Test 3: Single Server Operations Choose one server (recommend Vanilla 1.21.11 - lowest risk):

  • Toggle whitelist ON
  • Verify in Pterodactyl console
  • Add test player
  • Verify player added
  • Remove test player
  • Verify player removed
  • Toggle whitelist OFF

Test 4: Bulk Operations

  • Add player to all servers
  • Verify added to all 11 servers
  • Remove player from all servers
  • Verify removed from all 11 servers

Test 5: Error Handling

  • Test with invalid player name
  • Test with server down
  • Test with wrong API key (temporarily)
  • Verify error messages displayed

📝 PHASE 6: DEPLOY & DOCUMENT

Time Estimate: 15 minutes

Step 1: Roll Out to All Servers

Once testing passes:

  • Verify all 11 servers accessible via dashboard
  • Test whitelist status on each
  • Document any server-specific quirks
  1. Log into Wiki.js Staff (staff.firefrostgaming.com)
  2. Create new page or edit home page
  3. Add section: "Server Management Tools"
  4. Add link/button to whitelist manager
  5. Include brief usage instructions

Example Wiki.js Content:

## Server Management Tools

### Whitelist Manager
Manage player whitelists across all Minecraft servers from one interface.

[Open Whitelist Manager →](https://whitelist.firefrostgaming.com)

**Features:**
- Toggle whitelist on/off per server
- Add/remove players from individual servers
- Bulk add/remove across all servers
- View current whitelist status

**Access:** Admin/Staff only (same credentials as Wiki.js)

Step 3: Document in Git Repository

Create comprehensive documentation:

File 1: docs/tools/whitelist-manager-usage.md

  • User guide for staff
  • How to add/remove players
  • How to toggle whitelists
  • Troubleshooting common issues

File 2: docs/deployment/whitelist-manager-deployment.md

  • Technical deployment guide
  • Server configuration
  • Maintenance procedures
  • Recovery procedures

File 3: Update DOCUMENT-INDEX.md

  • Add references to new documentation

Step 4: Commit Code to Git

# In whitelist-manager directory
git init
git add .
git commit -m "Initial commit: Whitelist Manager v1.0"
git remote add origin https://git.firefrostgaming.com/firefrost-gaming/whitelist-manager.git
git push -u origin master

🔒 SECURITY CONSIDERATIONS

Authentication & Authorization

  • Basic HTTP authentication (username/password)
  • HTTPS enforced (no HTTP access)
  • API key stored server-side (never exposed to browser)
  • Future: OAuth/SSO integration with Wiki.js
  • Future: Role-based permissions (admin vs staff)

API Security

  • Pterodactyl API key with minimal required permissions
  • API key in environment variables (not config files)
  • Timeout on API requests (prevent hanging)
  • Error handling (don't expose internal details)

Network Security

  • Application bound to localhost (127.0.0.1)
  • Only accessible via Nginx reverse proxy
  • SSL/TLS encryption on all traffic
  • Firewall allows only 80/443 (Ghost VPS)

Logging & Auditing

  • All whitelist changes logged with timestamp
  • User actions logged (who added/removed what)
  • Failed authentication attempts logged
  • Log rotation configured

📊 MAINTENANCE & OPERATIONS

Daily Operations

Staff Usage:

  1. Navigate to https://whitelist.firefrostgaming.com
  2. Login with credentials
  3. View server dashboard
  4. Add/remove players as needed
  5. Toggle whitelist enforcement if needed

No maintenance required for normal operation

Weekly Tasks

  • Review logs for errors
  • Verify all servers responding
  • Check disk space for logs

Monthly Tasks

  • Review and archive old logs
  • Update Python dependencies (security patches)
  • Test backup/restore procedures

Monitoring

  • Add to Uptime Kuma (monitor whitelist.firefrostgaming.com)
  • Set up alerts for service down
  • Monitor log file size

🔄 FUTURE ENHANCEMENTS

Phase 2 Features

  1. Discord Bot Integration

    • /whitelist add player in Discord
    • Automated whitelist for paid subscribers
    • Notifications when players added/removed
  2. Paymenter Integration

    • Auto-whitelist on subscription payment
    • Auto-remove on subscription cancellation
    • Grace period handling
  3. Advanced Features

    • Whitelist sync verification (ensure all servers match)
    • Player activity tracking
    • Automated backups of whitelist.json files
    • Whitelist import/export
    • Bulk CSV upload
  4. UI Improvements

    • Real-time server status indicators
    • Player search/filter
    • Recent changes history
    • Multi-server selection (checkbox select)
  5. Authentication Upgrades

    • SSO integration with Wiki.js
    • Role-based permissions (admin/moderator/viewer)
    • 2FA support
    • API tokens for automation

🐛 TROUBLESHOOTING

Common Issues

Issue: Dashboard won't load

  • Check systemd service: systemctl status whitelist-manager
  • Check Nginx: nginx -t && systemctl status nginx
  • Check logs: tail -f /opt/firefrost/whitelist-manager/logs/whitelist-manager.log
  • Verify DNS: nslookup whitelist.firefrostgaming.com

Issue: Authentication fails

  • Verify credentials in .env file
  • Check Flask secret key set
  • Clear browser cache
  • Try incognito mode

Issue: Commands not executing

  • Verify Pterodactyl API key valid
  • Check API key permissions
  • Test API manually with curl
  • Check server UUID correct in config.json

Issue: SSL certificate errors

  • Re-run certbot: certbot renew --force-renewal
  • Check certificate files exist
  • Verify Nginx config pointing to correct cert paths

Recovery Procedures

Complete Service Restart:

systemctl stop whitelist-manager
systemctl stop nginx
systemctl start nginx
systemctl start whitelist-manager
systemctl status whitelist-manager

Reset to Clean State:

cd /opt/firefrost/whitelist-manager
git pull origin master
source venv/bin/activate
pip install -r requirements.txt
systemctl restart whitelist-manager

Emergency Fallback: If dashboard completely broken, use Pterodactyl console directly:

  1. Log into Pterodactyl panel
  2. Navigate to server console
  3. Execute commands manually:
    • /whitelist add PlayerName
    • /whitelist remove PlayerName
    • /whitelist on
    • /whitelist off

COMPLETION CHECKLIST

Pre-Deployment

  • Pterodactyl API key generated and tested
  • Ghost VPS SSH access verified
  • DNS A record created and propagated
  • Authentication credentials chosen
  • Whitelist enforcement method confirmed

Deployment

  • Application directory created
  • Python virtual environment set up
  • Dependencies installed
  • Configuration files created
  • Environment variables set
  • Flask app coded and tested locally
  • systemd service created and enabled
  • Nginx configured and tested
  • SSL certificate generated
  • Application accessible via HTTPS

Testing

  • Service health check passed
  • Web dashboard loads correctly
  • Authentication working
  • Single server whitelist toggle works
  • Add player to single server works
  • Remove player from single server works
  • Bulk add to all servers works
  • Bulk remove from all servers works
  • Error handling tested

Documentation

  • Usage guide created in Git
  • Deployment guide created in Git
  • Link added to Wiki.js Staff portal
  • Code committed to Git repository
  • DOCUMENT-INDEX.md updated
  • tasks.md updated with completion

Operations

  • Uptime Kuma monitor added
  • Staff trained on usage
  • Credentials stored in Vaultwarden
  • Maintenance schedule documented

📚 REFERENCES

Documentation

  • docs/troubleshooting/nc1-cleanup-guidelines.md - Server cleanup best practices
  • docs/troubleshooting/hytale-troubleshooting-guide.md - Game server troubleshooting
  • docs/core/tasks.md - Master task list
  • docs/core/project-scope.md - Infrastructure overview

Document Status: Ready for execution
Next Steps: Begin Phase 1 - Information Gathering
Owner: Michael "Frostystyle" Krause
Implementation Partner: The Chronicler

💙🔥❄️

Fire + Frost + Foundation = Where Love Builds Legacy