How to Install and Optimize Pterodactyl Panel on Your Dedicated Server
Running a game hosting company, an esports community, or simply hosting servers for friends requires robust management software. Pterodactyl Panel has become the absolute industry standard. It is a free, open-source game server management panel built with PHP, React, and Go, utilizing Docker to isolate every single game server instance for maximum security and performance.
However, installing Pterodactyl is not a one-click process. It requires configuring web servers, databases, caching mechanisms, and containerization daemons. Furthermore, running it on a bare-metal dedicated server gives you immense raw power, but to get the best out of your hardware, you need to optimize it.
In this comprehensive guide, we will walk you through a manual, production-ready installation of the latest Pterodactyl Panel (v1.12+) and its daemon (Wings) on a fresh Ubuntu 24.04 or Ubuntu 22.04 dedicated server here at FitServers. We will also include advanced optimization tweaks that standard guides leave out.
📋 Prerequisites
Before you SSH into your server, ensure you have the following ready:
- A bare-metal dedicated server running a fresh installation of Ubuntu 24.04 LTS or 22.04 LTS.
- Root access to your server.
- A fully qualified domain name (FQDN). For this tutorial, we will assume you are using panel.yourdomain.com.
- DNS 'A' records pointing panel.yourdomain.com to your dedicated server's public IPv4 address.
Step 1: Install Core Dependencies
First, log in to your server via SSH as the root user. Update your system packages to ensure everything is current:
apt update && apt upgrade -y
Next, we need to install essential software, including MariaDB (database), Redis (caching), Nginx (web server), and Composer (PHP dependency manager).
Pterodactyl v1.12+ requires PHP 8.3. Add the necessary repository and install the dependencies:
apt -y install software-properties-common curl apt-transport-https ca-certificates gnupg
LC_ALL=C.UTF-8 add-apt-repository -y ppa:ondrej/php
curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | sudo bash
apt update
apt -y install php8.3 php8.3-{cli,gd,mysql,pdo,mbstring,tokenizer,bcmath,xml,fpm,curl,zip} mariadb-server nginx tar unzip git redis-server
Install Composer:
curl -sS https://getcomposer.org/installer | sudo php -- --install-dir=/usr/local/bin --filename=composer
Step 2: Configure the Database
Secure your MariaDB installation and create a database and user for the Pterodactyl Panel.
Log into MariaDB:
mariadb -u root -p
(Press Enter when prompted for a password if this is a fresh install).
Run the following SQL commands to create the database (panel), user (pterodactyl), and grant permissions. Make sure to change YOUR_SECURE_PASSWORD to a strong password:
CREATE DATABASE panel;
CREATE USER 'pterodactyl'@'127.0.0.1' IDENTIFIED BY 'YOUR_SECURE_PASSWORD';
GRANT ALL PRIVILEGES ON panel.* TO 'pterodactyl'@'127.0.0.1' WITH GRANT OPTION;
FLUSH PRIVILEGES;
exit;
Step 3: Download and Install the Panel
Create the directory for the panel and download the latest release files.
mkdir -p /var/www/pterodactyl
cd /var/www/pterodactyl
curl -Lo panel.tar.gz https://github.com/pterodactyl/panel/releases/latest/download/panel.tar.gz
tar -xzvf panel.tar.gz
chmod -R 755 storage/* bootstrap/cache/
Set up the environment file and install the PHP dependencies:
cp .env.example .env
composer install --no-dev --optimize-autoloader
php artisan key:generate --force
Step 4: Environment Configuration
Now, we will configure the panel's environment variables (Database credentials, Redis, Mail). Run the interactive setup command:
php artisan p:environment:setup
- Author Email: Enter your admin email.
- Panel URL: https://panel.yourdomain.com
- Timezone: e.g., Europe/Amsterdam or America/New_York
- Cache/Session/Queue Driver: Select Redis for all three.
Configure the database connection:
php artisan p:environment:database
Enter the database details you created in Step 2 (Host: 127.0.0.1, Port: 3306, Database: panel, User: pterodactyl, Password: YOUR_SECURE_PASSWORD).
Set up database schemas and create your first Admin user:
php artisan migrate --seed --force
php artisan p:user:make
Follow the prompts to set your admin username, email, and password.
Step 5: File Permissions, Cron, and Workers
To ensure the panel runs smoothly, we must give Nginx ownership of the files:
chown -R www-data:www-data /var/www/pterodactyl/*
Pterodactyl requires a cronjob to run scheduled tasks every minute:
crontab -e
Add the following line to the bottom of the file:
* * * * * php /var/www/pterodactyl/artisan schedule:run >> /dev/null 2>&1
Next, create a Systemd service for the queue worker to process background tasks.
nano /etc/systemd/system/pteroq.service
Paste the following:
[Unit]
Description=Pterodactyl Queue Worker
After=redis-server.service
[Service]
User=www-data
Group=www-data
Restart=always
ExecStart=/usr/bin/php /var/www/pterodactyl/artisan queue:work --queue=high,standard,low --sleep=3 --tries=3
StartLimitInterval=180
StartLimitBurst=30
RestartSec=5s
[Install]
WantedBy=multi-user.target
Enable and start the worker and Redis:
systemctl enable --now pteroq.service
systemctl enable --now redis-server
Step 6: Web Server Configuration (Nginx & SSL)
Delete the default Nginx config and create one for Pterodactyl:
rm /etc/nginx/sites-enabled/default
nano /etc/nginx/sites-available/pterodactyl.conf
We will grab the official configuration layout. Be sure to replace <domain> with your actual domain (panel.yourdomain.com) and ensure the PHP version matches (php8.3-fpm):
server {
listen 80;
server_name <domain>;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name <domain>;
root /var/www/pterodactyl/public;
index index.html index.htm index.php;
charset utf-8;
# SSL Certs (We will generate these with Certbot shortly)
ssl_certificate /etc/letsencrypt/live/<domain>/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/<domain>/privkey.pem;
ssl_session_cache shared:SSL:10m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384";
ssl_prefer_server_ciphers on;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param PHP_VALUE "upload_max_filesize = 100M \n post_max_size=100M";
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTP_PROXY "";
fastcgi_intercept_errors off;
fastcgi_buffer_size 16k;
fastcgi_buffers 4 16k;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
}
location ~ /\.ht {
deny all;
}
}
Enable the configuration:
ln -s /etc/nginx/sites-available/pterodactyl.conf /etc/nginx/sites-enabled/pterodactyl.conf
Now, request a free SSL certificate from Let's Encrypt using Certbot:
apt install -y certbot python3-certbot-nginx
certbot certonly --nginx -d panel.yourdomain.com
Once generated, restart Nginx:
systemctl restart nginx
Your Pterodactyl Panel is now live! You can log in via your domain using the admin credentials you created.
Step 7: Installing Wings (The Daemon)
Wings is Pterodactyl's server control daemon, written in Go. It manages the Docker containers where your game servers run. You can run Wings on the same server as the Panel or on a separate dedicated server.
First, install Docker:
curl -sSL https://get.docker.com/ | CHANNEL=stable bash
systemctl enable --now docker
Enable Swap in GRUB (Crucial for Docker memory limits):
sed -i 's/GRUB_CMDLINE_LINUX_DEFAULT="/GRUB_CMDLINE_LINUX_DEFAULT="swapaccount=1 /' /etc/default/grub
update-grub
(You should reboot your server after the installation is complete to apply this).
Install the Wings binary:
mkdir -p /etc/pterodactyl
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")"
chmod u+x /usr/local/bin/wings
Now, log in to your Pterodactyl Panel web interface:
- Go to the Admin control panel.
- Navigate to Locations and create a new location (e.g., "FitServers-EU").
- Navigate to Nodes and click Create New.
- Fill in the details:
- Name: Main Node
- Location: Select your location.
- FQDN: Enter panel.yourdomain.com (or the IP if running Wings on a separate server).
- Total Memory: Enter your server's RAM in MB.
- Total Disk Space: Enter your server's storage in MB.
- Save the Node, then go to the Configuration tab for that Node. Click Generate Token.
- Copy the configuration command (it looks like cd /etc/pterodactyl && sudo wings configure ...).
- Paste that configuration command into your server's SSH terminal.
Finally, create a Systemd service for Wings:
nano /etc/systemd/system/wings.service
Paste the following:
[Unit]
Description=Pterodactyl Wings Daemon
After=docker.service
Requires=docker.service
PartOf=docker.service
[Service]
User=root
WorkingDirectory=/etc/pterodactyl
LimitNOFILE=4096
PIDFile=/var/run/wings/daemon.pid
ExecStart=/usr/local/bin/wings
Restart=on-failure
StartLimitInterval=180
StartLimitBurst=30
RestartSec=5s
[Install]
WantedBy=multi-user.target
Enable and start Wings:
systemctl enable --now wings
If you check your Panel now, the Node should show a green heart, meaning it is successfully connected!
⚡ Optimization Secrets for FitServers Dedicated Hardware
A standard installation works well, but to extract enterprise-grade performance from your bare-metal server, apply these optimizations:
-
1. MariaDB Performance Tuning
Game servers running on Pterodactyl (especially large Minecraft networks or FiveM servers) query the database constantly.
Open /etc/mysql/mariadb.conf.d/50-server.cnf and adjust the InnoDB buffer pool based on your server RAM. If you have a 64GB dedicated server, you can safely allocate 4GB to the database:
INIinnodb_buffer_pool_size = 4G innodb_log_file_size = 1G innodb_flush_log_at_trx_commit = 2Restart MariaDB: systemctl restart mariadb.
-
2. Nginx File Upload Limits
By default, Nginx limits uploads to 1MB. If a user tries to upload a custom game map via the Panel web interface, it will fail.
Open /etc/nginx/nginx.conf and add/modify this inside the http {} block:
Nginxclient_max_body_size 1024M; client_body_buffer_size 128k;Restart Nginx: systemctl restart nginx.
-
3. Docker Overlay2 and IOPS Limits
If you are running IO-heavy games (like Rust), you must ensure your Docker storage driver is using overlay2. Furthermore, if you are using NVMe drives provided by FitServers, you can modify specific server containers in the Pterodactyl Panel settings to have unmetered IOPS limits (Set Block IO Weight to 1000).
-
4. Bypassing Cloudflare for Wings Traffic
If you put your Panel behind Cloudflare to hide the IP, make sure your Node (Wings) traffic bypasses the proxy. Routing game server SFTP (Port 2022) or Wings communication (Port 8080) through Cloudflare's HTTP proxy will cause connections to time out and break the console. Create a separate subdomain (e.g., node.yourdomain.com), turn off the orange Cloudflare proxy cloud (DNS only), and assign that to your Node FQDN in the Panel.
Ready for Deployment
Your dedicated server is now running a highly optimized, secure, and production-ready Pterodactyl Panel. You are ready to start creating game servers, allocating resources, and assigning users!