# 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 ```bash # Create DNS A Record # Domain: whitelist.firefrostgaming.com # Type: A # Value: [Ghost VPS IP Address] # TTL: 300 # Proxy: Off (for initial setup) ``` **Verification:** ```bash # Wait 5 minutes, then test: nslookup whitelist.firefrostgaming.com # Should return Ghost VPS IP ``` ### Step 2: SSH into Ghost VPS ```bash ssh root@[ghost-vps-ip] ``` ### Step 3: Create Application Directory ```bash # 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 ```bash # 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 ```bash # 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` ```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` ```bash # 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:** ```bash 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` ```python #!/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//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//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//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//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` ```ini [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:** ```bash 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` ```nginx 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:** ```bash ln -s /etc/nginx/sites-available/whitelist.firefrostgaming.com /etc/nginx/sites-enabled/ nginx -t systemctl reload nginx ``` ### Step 3: Generate SSL Certificate ```bash certbot --nginx -d whitelist.firefrostgaming.com ``` --- ## 📝 PHASE 5: TESTING **Time Estimate:** 15 minutes ### Test Plan **Test 1: Application Health** ```bash # 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** - Navigate to https://whitelist.firefrostgaming.com - Verify SSL certificate valid - Login with credentials - Dashboard loads correctly **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 ### Step 2: Add Link to Wiki.js Staff Portal 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:** ```markdown ## 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 ```bash # 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:** ```bash systemctl stop whitelist-manager systemctl stop nginx systemctl start nginx systemctl start whitelist-manager systemctl status whitelist-manager ``` **Reset to Clean State:** ```bash 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 - Pterodactyl API: https://dashflo.net/docs/api/pterodactyl/v1/ - Flask Documentation: https://flask.palletsprojects.com/ - Nginx Reverse Proxy: https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/ - Let's Encrypt: https://letsencrypt.org/docs/ ### Related Firefrost Docs - `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**