VPS Tutorials
Building a Pterodactyl Game Server Panel on a VPS (2026): Complete Tutorial for Panel, Wings, Docker, HTTPS and Backups
Deploy Pterodactyl Panel and Wings on a VPS: covering server configuration, Docker nodes, domain HTTPS, Eggs, port allocation, game server creation, backups, security hardening and common troubleshooting.

Building a Pterodactyl Game Server Panel on a VPS (2026): Complete Tutorial for Panel, Wings, Docker, HTTPS and Backups
If you want to manage multiple game servers such as Minecraft, Rust, Palworld and CS2 from a single VPS, Pterodactyl is an open-source solution with both high search volume and real-world adoption. It does not "automatically give you performance once the panel is installed"; rather, it unifies users, game instances, resource limits, files, consoles and backups. What actually runs the game processes is still your CPU, memory, disk and network.
This article follows the official Pterodactyl 1.x workflow to explain the division of labor between Panel and Wings, how to choose a VPS, how to configure domains and HTTPS, and what to check when a node goes offline, ports are unreachable, or backups cannot be restored.
Pterodactyl consists of two parts:
- Panel: a Laravel web admin backend that stores users, servers, Eggs, nodes and permission data.
- Wings: a Go service installed on game nodes that starts and stops game containers via Docker.
A Node in the Panel corresponds to a server running Wings; an Allocation is an IP and port combination assigned to a game server; an Egg defines the game image, startup command, variables and install script.
Panel and Wings can be installed on the same KVM VPS, which suits personal servers and small-scale testing. When you need to host multiple users or multiple nodes, it is better to separate the Panel, database and game nodes, so that a game server maxing out CPU does not make the admin backend unreachable.
The Panel itself is not heavy; game servers are the resource hogs. Before buying, estimate based on the game, player count, plugins and map size.
| Scenario | Suggested starting configuration | Notes |
|---|---|---|
| Panel only | 2 cores 2GB, 30GB SSD | Panel, MariaDB, Redis, Nginx |
| Small Minecraft server | 4 cores 8GB, 80GB NVMe | Suitable for a few players and lightweight plugins |
| Multiple game instances | 6–8 cores, 16GB+, 160GB NVMe | Resources need to be reserved for each instance |
| Heavy games like Rust, Palworld | High-clock CPU, 16GB+, NVMe | Prioritize single-core performance, disk and DDoS protection |
The official documentation explicitly states: Wings requires Linux that can run Docker properly. KVM works reliably; OpenVZ, Virtuozzo and some LXC environments often lack the required capabilities. Before buying, you can run:
systemd-detect-virt
If the result is openvz or lxc, first confirm Docker and nested container support with your provider. For more complete game server selection advice, see Game Server VPS Recommendations.
The current official documentation supports Ubuntu 22.04/24.04, Debian 11/12/13, as well as RHEL, Rocky Linux and AlmaLinux 8/9. The example below uses Ubuntu 24.04.
It is recommended to prepare two domains:
panel.example.com: Panel admin backend;node.example.com: Wings node.
Common public ports include:
- 80/443: Panel web and HTTPS;
- 8080 or 8443: Wings HTTP/HTTPS API;
- 2022: Wings SFTP;
- Game ports: for example Minecraft commonly uses 25565, but the Egg and actual Allocation should be authoritative.
First check for conflicts:
sudo ss -lntup | grep -E ':(80|443|8080|8443|2022)\b' || true
If you find a port in use, do not simply stop an unknown process; first confirm which service owns it using the VPS Port Occupied Troubleshooting Guide.
Pterodactyl Panel currently requires PHP 8.2 or 8.3, MySQL 5.7.22+ or MariaDB 10.2+, Redis, a web server, Composer 2, and Git, curl, tar, unzip. On Ubuntu 24.04 you can install PHP 8.3:
sudo apt update
sudo apt install -y \
php8.3 php8.3-{common,cli,gd,mysql,mbstring,bcmath,xml,fpm,curl,zip} \
mariadb-server nginx redis-server tar unzip git curl
curl -sS https://getcomposer.org/installer \
| sudo php -- --install-dir=/usr/local/bin --filename=composer
Create the database and a dedicated user; the password must be replaced with a random strong password:
CREATE USER 'pterodactyl'@'127.0.0.1' IDENTIFIED BY '替换为强密码';
CREATE DATABASE panel;
GRANT ALL PRIVILEGES ON panel.* TO 'pterodactyl'@'127.0.0.1' WITH GRANT OPTION;
EXIT;
sudo mkdir -p /var/www/pterodactyl
cd /var/www/pterodactyl
sudo curl -Lo panel.tar.gz \
https://github.com/pterodactyl/panel/releases/latest/download/panel.tar.gz
sudo tar -xzvf panel.tar.gz
sudo chmod -R 755 storage/* bootstrap/cache/
sudo cp .env.example .env
sudo COMPOSER_ALLOW_SUPERUSER=1 composer install --no-dev --optimize-autoloader
sudo php artisan key:generate --force
APP_KEY is used to decrypt sensitive data such as API keys. If you back up only the database and lose .env, you may still get Invalid MAC after restoring, so save this line immediately to a password manager or a separate encrypted backup:
grep APP_KEY /var/www/pterodactyl/.env
Continue configuring the environment, database and mail:
sudo php artisan p:environment:setup
sudo php artisan p:environment:database
sudo php artisan p:environment:mail
sudo php artisan migrate --seed --force
sudo php artisan p:user:make
sudo chown -R www-data:www-data /var/www/pterodactyl/*
SMTP is recommended for mail. Do not interrupt migrate --seed --force during initialization; it creates the data tables and writes Nests and Eggs.
The Panel's Nginx configuration should follow the official Webserver Configuration template matching your system, and the site root must point to:
/var/www/pterodactyl/public
First point panel.example.com to the VPS, then request a Let's Encrypt certificate. Once the Panel uses HTTPS, Wings must also use HTTPS matching the Node FQDN, otherwise browsers and the Panel will block insecure connections.
Add a scheduled task that runs every minute:
* * * * * php /var/www/pterodactyl/artisan schedule:run >> /dev/null 2>&1
The core startup command for the queue worker is:
/usr/bin/php /var/www/pterodactyl/artisan queue:work --queue=high,standard,low --sleep=3 --tries=3
Place the official pteroq.service into /etc/systemd/system/ and enable it:
sudo systemctl enable --now redis-server
sudo systemctl enable --now pteroq.service
If scheduled tasks do not run, check systemctl status pteroq, journalctl -xeu pteroq, the PHP version and the system timezone in order.
Wings officially depends only on curl and Docker. For production, installing from the official Docker repository is recommended; for quick verification you can use:
curl -sSL https://get.docker.com/ | CHANNEL=stable bash
sudo systemctl enable --now docker
sudo mkdir -p /etc/pterodactyl
sudo curl -L -o /usr/local/bin/wings \
"https://github.com/pterodactyl/wings/releases/latest/download/wings_linux_$([[ "$(uname -m)" == "x86_64" ]] && echo "amd64" || echo "arm64")"
sudo chmod u+x /usr/local/bin/wings
In the Panel backend, go to Admin → Nodes → Create New to create a node, then open that node's Configuration and save the configuration to:
/etc/pterodactyl/config.yml
First start in debug mode:
sudo wings --debug
After confirming there are no errors, create the systemd service following the official wings.service and enable it:
sudo systemctl enable --now wings
sudo systemctl status wings
Go to Nodes → 节点 → Allocation and fill in the server's real network interface IP and game port range. The official documentation explicitly requires not using 127.0.0.1 as an Allocation. You can view addresses with the following command:
hostname -I | awk '{print $1}'
Then:
- In Admin, select Servers and create a server;
- Select the Node, Allocation, Nest and Egg;
- Set memory, disk, CPU and backup count;
- Confirm the Docker image and startup variables;
- After creation, watch the install output in the console.
Do not allocate all of the node's memory. The host system, Docker, Wings, Panel and database all need headroom. When hosting publicly, you should also limit CPU, disk and process count to prevent one user from bringing down the whole machine.
Only open the ports that are actually needed:
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 8080/tcp
sudo ufw allow 2022/tcp
sudo ufw allow 25565/tcp
sudo ufw enable
If Wings uses 8443, do not also open the unused 8080. Game ports should be opened precisely according to Allocations; do not open all ports just for convenience.
When a node shows a red heart or "Cannot connect to server", check in order:
sudo systemctl status wings
sudo journalctl -u wings -n 100 --no-pager
sudo wings --debug
dig +short node.example.com
curl -vk https://node.example.com:8443
Key things to verify:
- Whether the Node Configuration in the Panel matches
/etc/pterodactyl/config.yml; - Whether Wings also uses a valid certificate when the Panel uses HTTPS;
- Whether 8080/8443 and 2022 are blocked by a firewall, security group or NAT;
- Whether the Node FQDN resolves to the correct IP;
- Whether the Cloudflare proxy changes ports or SSL mode.
Cloudflare cannot hide a node's IP for game traffic. Even if Wings goes through a proxy, players still connect directly to game ports; real DDoS protection should come from the data center, provider scrubbing or a dedicated proxy.
Back up at least four parts:
- The Panel's MariaDB/MySQL database;
/var/www/pterodactyl/.env, especiallyAPP_KEY;/etc/pterodactyl/config.yml;- Wings' game data and backup directory.
By default, local backups are stored via Wings, but keeping them on the same VPS disk as the game data cannot protect against whole-machine failure. In production, you can use S3-compatible backups in the Panel .env:
APP_BACKUP_DRIVER=s3
AWS_DEFAULT_REGION=auto
AWS_ACCESS_KEY_ID=替换为访问密钥
AWS_SECRET_ACCESS_KEY=替换为秘密密钥
AWS_BACKUPS_BUCKET=替换为存储桶
AWS_ENDPOINT=https://你的S3兼容端点
After setting up backups, you must perform a restore drill to confirm that the database, APP_KEY, Egg configuration and game saves can be restored together. You can combine this with the VPS Backup and Restore Drill Guide.
| Solution | Advantages | Better suited for |
|---|---|---|
| Pterodactyl | Mature ecosystem, rich Eggs, complete multi-node and permissions | Multiple games, multiple users, hosting scenarios |
| Pelican | Continues a similar architecture, newer project | Users willing to evaluate a new ecosystem |
| PufferPanel | Relatively straightforward to deploy and use | Home servers, small-scale self-hosting |
| Vendor game panels | Least operational effort | Those who do not want to manage Linux and Docker |
If Pterodactyl is already running stably, do not rush to migrate just for interface changes. Backups, monitoring, DDoS protection and node capacity are usually more important than switching panels.
No. Personal servers can be deployed on the same machine; multi-node or commercial hosting is better separated so game load does not affect the admin backend.
In most cases it is unreliable. The official documentation states that OpenVZ, Virtuozzo and some LXC may not be able to run the required Docker features; prefer KVM.
Usually because Wings is not running, configurations are inconsistent, DNS is wrong, the certificate is invalid, or 8080/8443 is blocked by a firewall.
No. It manages game containers; it does not replace data-center-level scrubbing, Anycast protection or game traffic proxies.
Because encrypted data also depends on the original APP_KEY. The database, Panel .env, Wings configuration and game data must be backed up together.
The hard part of Pterodactyl is not downloading the Panel, but connecting the web, database, Redis, queues, Wings, Docker, DNS, certificates and game ports into one reliable chain. Small-scale deployments can start with a single 4-core 8GB KVM VPS; when preparing to host multiple players or heavy games, prioritize high-clock CPUs, NVMe, ample memory and lines with genuine DDoS protection.
Before going live, do three final things: save APP_KEY, verify that S3 or off-machine backups can be restored, and test the Panel, Wings SFTP and every game Allocation port from the external network.