Migrating whitelist-manager-deployment-plan.md: - FROM: docs/tools/whitelist-manager-deployment-plan.md - TO: docs/tasks/whitelist-manager/deployment-plan.md Following FFG-STD-002 naming convention: - Task-specific docs live in docs/tasks/[task-name]/ - Renamed to standard name: deployment-plan.md Content unchanged - this is a pure migration. Next step: Delete old location (docs/tools/) Phase 3 of complete restructure. Date: February 16, 2026 Implemented by: The Chronicler
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):
- Reclamation - TX (
1eb33479-a6bc-4e8f-b64d-d1e4bfa0a8b4) - The Ember Project - NC (
124f9060-58a7-457a-b2cf-b4024fce2951) - Stoneblock 4 - TX (
a0efbfe8-4b97-4a90-869d-ffe6d3072bd5) - Minecolonies: Create and Conquer - NC (
a14201d2-83b2-44e6-ae48-e6c4cbc56f24) - Society: Sunlit Valley - TX (
9310d0a6-62a6-4fe6-82c4-eb483dc68876) - All The Mods 10 - NC (
82e63949-8fbf-4a44-b32a-53324e8492bf) - Vanilla 1.21.11 - TX (
3bed1bda-f648-4630-801a-fe9f2e3d3f27) - Homestead - NC (
2f85d4ef-aa49-4dd6-b448-beb3fca1db12) - All The Mons - TX (
668a5220-7e72-4379-9165-bdbb84bc9806) - 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
- 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
- Log into Wiki.js Staff (staff.firefrostgaming.com)
- Create new page or edit home page
- Add section: "Server Management Tools"
- Add link/button to whitelist manager
- 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:
- Navigate to https://whitelist.firefrostgaming.com
- Login with credentials
- View server dashboard
- Add/remove players as needed
- 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
-
Discord Bot Integration
/whitelist add playerin Discord- Automated whitelist for paid subscribers
- Notifications when players added/removed
-
Paymenter Integration
- Auto-whitelist on subscription payment
- Auto-remove on subscription cancellation
- Grace period handling
-
Advanced Features
- Whitelist sync verification (ensure all servers match)
- Player activity tracking
- Automated backups of whitelist.json files
- Whitelist import/export
- Bulk CSV upload
-
UI Improvements
- Real-time server status indicators
- Player search/filter
- Recent changes history
- Multi-server selection (checkbox select)
-
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
.envfile - 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:
- Log into Pterodactyl panel
- Navigate to server console
- 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 practicesdocs/troubleshooting/hytale-troubleshooting-guide.md- Game server troubleshootingdocs/core/tasks.md- Master task listdocs/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