╔══════════════════════════════════════════════════════════════════╗ ║ PTERODACTYL PANEL & WINGS INSTALLATION GUIDE ║ ║ Complete Step-by-Step Walkthrough ║ ╚══════════════════════════════════════════════════════════════════╝ ┌─────────────────────────────────────────────────────────────────┐ │ STEP 1: START THE INSTALLATION │ └─────────────────────────────────────────────────────────────────┘ Run this command as root: # bash <(curl -s https://pterodactyl-installer.se) ┌─────────────────────────────────────────────────────────────────┐ │ STEP 2: SELECT INSTALLATION TYPE │ └─────────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────┐ │ Which version of Pterodactyl do you want to install? │ │ 1) Panel │ │ 2) Wings │ │ 3) Both (Panel & Wings) │ └─────────────────────────────────────────────────────────────┘ >>> SELECT: 3 (BOTH) > Type "3" and press ENTER ┌─────────────────────────────────────────────────────────────────┐ │ STEP 3: CONFIRM INSTALLATION │ └─────────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────┐ │ * Are you sure you want to continue? (y/N): │ └─────────────────────────────────────────────────────────────┘ >>> SELECT: y (YES) > Type "y" and press ENTER ┌─────────────────────────────────────────────────────────────────┐ │ STEP 4: DATABASE CONFIGURATION │ └─────────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────┐ │ * Do you want to automatically configure the database? │ │ (y/N): │ └─────────────────────────────────────────────────────────────┘ >>> SELECT: y (YES) > Type "y" and press ENTER ┌─────────────────────────────────────────────────────────────────┐ │ STEP 5: DATABASE USERNAME & PASSWORD │ └─────────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────┐ │ * Database host username (pterodactyluser): │ └─────────────────────────────────────────────────────────────┘ >>> LEAVE BLANK: Press ENTER (uses default) ┌─────────────────────────────────────────────────────────────┐ │ * Database host password: │ └─────────────────────────────────────────────────────────────┘ >>> IMPORTANT! Type a strong password (write it down!) > Example: MyStr0ngP@ssw0rd!2026 > Press ENTER after typing ┌─────────────────────────────────────────────────────────────────┐ │ STEP 6: MYSQL EXTERNAL ACCESS │ └─────────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────┐ │ * Do you want to configure MySQL to be accessed │ │ externally? (y/N): │ └─────────────────────────────────────────────────────────────┘ >>> SELECT: n (NO) > Type "n" and press ENTER ┌─────────────────────────────────────────────────────────────────┐ │ STEP 7: EMAIL CONFIGURATION │ └─────────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────┐ │ * Enter your email address for the panel: │ └─────────────────────────────────────────────────────────────┘ >>> Type your email: admin@example.com > Press ENTER ┌─────────────────────────────────────────────────────────────┐ │ * Enter your company/panel name: │ └─────────────────────────────────────────────────────────────┘ >>> Type a name: My Game Panel > Or leave blank: Press ENTER ┌─────────────────────────────────────────────────────────────────┐ │ STEP 8: CREATE ADMIN USER │ └─────────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────┐ │ * Would you like to create an admin user? (y/N): │ └─────────────────────────────────────────────────────────────┘ >>> SELECT: y (YES) > Type "y" and press ENTER ┌─────────────────────────────────────────────────────────────┐ │ * Enter your email address: │ └─────────────────────────────────────────────────────────────┘ >>> Type your admin email: admin@example.com ┌─────────────────────────────────────────────────────────────┐ │ * Enter your username: │ └─────────────────────────────────────────────────────────────┘ >>> Type your username: admin ┌─────────────────────────────────────────────────────────────┐ │ * Enter your first name: │ └─────────────────────────────────────────────────────────────┘ >>> Type your first name: John ┌─────────────────────────────────────────────────────────────┐ │ * Enter your last name: │ └─────────────────────────────────────────────────────────────┘ >>> Type your last name: Doe ┌─────────────────────────────────────────────────────────────┐ │ * Enter your password: │ └─────────────────────────────────────────────────────────────┘ >>> IMPORTANT! Type a strong password (write it down!) > Example: Admin@2026#Secure! > Press ENTER ┌─────────────────────────────────────────────────────────────────┐ │ STEP 9: SSL CONFIGURATION (PANEL) │ └─────────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────┐ │ * Do you want to use Let's Encrypt SSL? (y/N): │ └─────────────────────────────────────────────────────────────┘ +------------------------------------------------------------------+ | IF YOU HAVE A DOMAIN NAME: | | SELECT: y (YES) | | Then enter your domain: panel.example.com | | | | IF YOU ONLY HAVE AN IP ADDRESS (NO DOMAIN): | | SELECT: n (NO) | | The panel will use HTTP (port 80) | | | | IF USING REVERSE PROXY (Nginx/Apache as proxy): | | SELECT: n (NO) | | We'll configure SSL later in Nginx | +------------------------------------------------------------------+ >>> Choose based on your setup > Type "y" or "n" and press ENTER ┌─────────────────────────────────────────────────────────────────┐ │ STEP 10: WINGS CONFIGURATION (UFW FIREWALL) │ └─────────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────┐ │ * Do you want to automatically configure UFW (firewall)? │ │ (y/N): │ └─────────────────────────────────────────────────────────────┘ >>> SELECT: y (YES) - Recommended! > Type "y" and press ENTER ┌─────────────────────────────────────────────────────────────────┐ │ STEP 11: DATABASE USER FOR WINGS │ └─────────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────┐ │ * Do you want to configure a user for database hosts? │ │ (y/N): │ └─────────────────────────────────────────────────────────────┘ >>> SELECT: y (YES) > Type "y" and press ENTER ┌─────────────────────────────────────────────────────────────┐ │ * Database host username (pterodactyluser): │ └─────────────────────────────────────────────────────────────┘ >>> LEAVE BLANK: Press ENTER ┌─────────────────────────────────────────────────────────────┐ │ * Database host password: │ └─────────────────────────────────────────────────────────────┘ >>> Type a password (write it down!) > Example: WingsDB@2026#Strong! > Press ENTER ┌─────────────────────────────────────────────────────────────┐ │ * Do you want to configure MySQL to be accessed externally? │ │ (y/N): │ └─────────────────────────────────────────────────────────────┘ >>> SELECT: n (NO) > Type "n" and press ENTER ┌─────────────────────────────────────────────────────────────────┐ │ STEP 12: SSL FOR WINGS │ └─────────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────┐ │ * Do you want to automatically configure HTTPS using │ │ Let's Encrypt? (y/N): │ └─────────────────────────────────────────────────────────────┘ +------------------------------------------------------------------+ | IF YOU HAVE A DOMAIN AND WANT SSL DIRECTLY: | | SELECT: y (YES) | | | | IF USING REVERSE PROXY OR IP ONLY: | | SELECT: n (NO) | | We'll configure SSL via reverse proxy later | +------------------------------------------------------------------+ >>> SELECT: n (NO) - if using reverse proxy > Type "n" and press ENTER ┌─────────────────────────────────────────────────────────────────┐ │ STEP 13: FINAL CONFIRMATION │ └─────────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────┐ │ * Proceed with installation? (y/N): │ └─────────────────────────────────────────────────────────────┘ >>> SELECT: y (YES) > Type "y" and press ENTER > Wait for installation to complete (2-5 minutes) +------------------------------------------------------------------+ | INSTALLATION COMPLETE! | | | | Your Pterodactyl Panel is now installed! | | | | Access your panel at: | | http://YOUR_SERVER_IP | | or | | https://YOUR_DOMAIN (if SSL enabled) | | | | Login with: | | Email: [your admin email] | | Password: [your admin password] | | | | IMPORTANT: Your Wings still needs to be configured! | | 1. Log into the panel | | 2. Go to Admin -> Nodes -> Create New | | 3. Generate the configuration file | | 4. Copy it to /etc/pterodactyl/config.yml | | 5. Run: systemctl start wings | +------------------------------------------------------------------+ ┌─────────────────────────────────────────────────────────────────┐ │ QUICK REFERENCE SHEET │ └─────────────────────────────────────────────────────────────────┘ +--------------+-------------+----------------------------------+ | QUESTION | ANSWER | REASON | +--------------+-------------+----------------------------------+ | Panel/Wings | 3 (Both) | Install everything at once | | Continue? | y | Start installation | | Auto DB? | y | Let script handle DB | | DB username | [ENTER] | Use default | | DB password | [TYPE] | Strong password (save it) | | MySQL ext | n | No external access needed | | Admin user? | y | Create admin account | | Let's Encrypt| n or y | n = IP/proxy, y = domain | | Configure | y | Auto open firewall ports | | UFW? | | | | Wings DB | y | Create DB user for Wings | | Wings SSL | n | n = proxy, y = direct | +--------------+-------------+----------------------------------+ ┌─────────────────────────────────────────────────────────────────┐ │ FIREWALL PORTS TO OPEN │ └─────────────────────────────────────────────────────────────────┘ +-------------------------------------------------------------+ | Port 80 - HTTP (Web Panel) | | Port 443 - HTTPS (Web Panel) - if SSL enabled | | Port 8080 - Wings WebSocket (Server communication) | | Port 2022 - SFTP (File transfer for servers) | +-------------------------------------------------------------+ ┌─────────────────────────────────────────────────────────────────┐ │ COMMON ERRORS & SOLUTIONS │ └─────────────────────────────────────────────────────────────────┘ ERROR: "No application encryption key has been specified" -------------------------------------------------------------- SOLUTION: php /var/www/pterodactyl/artisan key:generate --force ERROR: "Unknown database 'panel'" -------------------------------------------------------------- SOLUTION: mysql -u root -p -e "CREATE DATABASE panel;" ERROR: "Connection refused" on Wings -------------------------------------------------------------- SOLUTION: Check if port 8080 is open: netstat -tlnp | grep 8080 Also check: systemctl status wings ERROR: "403 Forbidden" on panel -------------------------------------------------------------- SOLUTION: chown -R www-data:www-data /var/www/pterodactyl/storage chmod -R 755 /var/www/pterodactyl/storage ERROR: "502 Bad Gateway" on panel -------------------------------------------------------------- SOLUTION: systemctl restart php8.2-fpm systemctl restart nginx ERROR: "allowed_origins" missing in Wings config -------------------------------------------------------------- SOLUTION: Add to /etc/pterodactyl/config.yml: allowed_origins: - https://your-domain.com ERROR: Panel shows "500 Internal Server Error" -------------------------------------------------------------- SOLUTION: Check logs: tail -f /var/www/pterodactyl/storage/logs/*.log Clear cache: php /var/www/pterodactyl/artisan config:clear ┌─────────────────────────────────────────────────────────────────┐ │ POST-INSTALLATION: WINGS SETUP │ └─────────────────────────────────────────────────────────────────┘ 1. Login to panel: http://YOUR_SERVER_IP 2. Go to: Admin -> Nodes -> Create New 3. Fill in: * Name: Main Node * Description: (optional) * Location: (optional) * Allow Automatic Allocation: Yes * FQDN: YOUR_SERVER_IP or domain * Daemon Port: 443 (or 8080 if using proxy) * Communicate over SSL: Yes (if using SSL) * Behind Proxy: Yes (if using reverse proxy) * Public: Yes 4. After creating, click on the node -> Configuration 5. Copy the configuration code and: - If using reverse proxy: change port 443 to 8080 - If using direct SSL: keep port 443 6. Add allowed_origins after allowed_mounts: allowed_mounts: [] allowed_origins: - https://your-domain.com - https://panel.your-domain.com 7. Save to: /etc/pterodactyl/config.yml 8. Start Wings: systemctl start wings systemctl enable wings ┌─────────────────────────────────────────────────────────────────┐ │ NGINX REVERSE PROXY EXAMPLE CFG │ │ (For Panel + Wings Behind Proxy) │ └─────────────────────────────────────────────────────────────────┘ upstream pterodactyl { server 127.0.0.1:80; # Panel port } upstream pterodactyl_ws { server 127.0.0.1:8080; # Wings WebSocket port } server { listen 80; server_name panel.your-domain.com; return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name panel.your-domain.com; ssl_certificate /etc/letsencrypt/live/panel.your-domain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/panel.your-domain.com/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; client_max_body_size 10G; # WebSocket connections location = /api/system { proxy_pass http://pterodactyl_ws; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; 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 https; proxy_set_header Origin https://panel.your-domain.com; proxy_buffering off; } # File uploads/downloads location /upload/ { proxy_pass http://pterodactyl_ws; proxy_http_version 1.1; 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 https; proxy_set_header Origin https://panel.your-domain.com; client_max_body_size 10G; } location /download/ { proxy_pass http://pterodactyl_ws; proxy_http_version 1.1; 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 https; proxy_set_header Origin https://panel.your-domain.com; proxy_buffering off; } # API endpoints with WebSocket location ~ ^/api/servers { proxy_pass http://pterodactyl_ws; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; 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 https; proxy_set_header Origin https://panel.your-domain.com; proxy_read_timeout 3600s; proxy_send_timeout 3600s; proxy_buffering off; } # Main panel location / { proxy_pass http://pterodactyl; 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 https; } } ┌─────────────────────────────────────────────────────────────────┐ │ TROUBLESHOOTING COMMANDS │ └─────────────────────────────────────────────────────────────────┘ # Check panel status systemctl status nginx systemctl status php8.2-fpm # Check wings status systemctl status wings # View panel logs tail -f /var/www/pterodactyl/storage/logs/laravel-*.log # View wings logs journalctl -u wings -f # Restart panel services systemctl restart nginx php8.2-fpm # Restart wings systemctl restart wings # Generate application key (if needed) php /var/www/pterodactyl/artisan key:generate --force # Clear cache php /var/www/pterodactyl/artisan config:clear php /var/www/pterodactyl/artisan cache:clear php /var/www/pterodactyl/artisan view:clear # Check MySQL status systemctl status mysql mysql -u root -p -e "SHOW DATABASES;" # Check open ports netstat -tlnp | grep -E ':80|:443|:8080|:2022' # Check if Wings can connect to panel curl -I https://panel.your-domain.com ┌─────────────────────────────────────────────────────────────────┐ │ BACKUP COMMANDS │ └─────────────────────────────────────────────────────────────────┘ # Backup panel files tar -czf /root/panel_backup_$(date +%Y%m%d).tar.gz /var/www/pterodactyl # Backup database mysqldump -u root -p panel > /root/panel_db_backup_$(date +%Y%m%d).sql # Backup Wings config cp /etc/pterodactyl/config.yml /root/config.yml.backup # Backup Nginx config cp -r /etc/nginx/sites-available /root/nginx_backup/ # Restore database mysql -u root -p panel < /root/panel_db_backup_YYYYMMDD.sql ┌─────────────────────────────────────────────────────────────────┐ │ SECURITY RECOMMENDATIONS │ └─────────────────────────────────────────────────────────────────┘ [1] Change default admin password after first login [2] Enable 2FA for admin accounts [3] Use HTTPS with valid SSL certificates (Let's Encrypt) [4] Regular backups: .env, database, Wings config [5] Update regularly: apt update && apt upgrade [6] Monitor logs: /var/www/pterodactyl/storage/logs/ [7] Set up fail2ban to protect SSH and panel [8] Use strong passwords (min 12 chars, mix of chars) [9] Limit SSH access: edit /etc/ssh/sshd_config [10] Disable root login: PermitRootLogin no [11] Use firewall: ufw enable (if not already) [12] Change default MySQL port (3306) if exposed externally ┌─────────────────────────────────────────────────────────────────┐ │ IMPORTANT NOTES │ └─────────────────────────────────────────────────────────────────┘ [*] SAVE ALL PASSWORDS: Panel DB, Admin user, Wings DB [*] Wait for migrations to complete (may take 2-5 minutes) [*] If using IP instead of domain, you'll see a security warning (This is normal, just proceed) [*] For production, always use a domain with SSL certificates [*] Backup /var/www/pterodactyl/.env file after installation [*] Keep your panel and Wings versions in sync [*] Monitor disk space - server files can grow quickly! [*] Use separate database for each server if hosting many nodes +------------------------------------------------------------------+ | INSTALLATION SUCCESS! | | | | Your Pterodactyl Panel is now ready for use! | | | | Documentation: https://pterodactyl.io/docs | | | | Next steps: | | 1. Configure Wings (see post-installation) | | 2. Set up your first game server | | 3. Configure email notifications | | 4. Set up regular backups | | 5. Monitor performance | +------------------------------------------------------------------+