Game Servers
    Panel

    Deploy Pelican Panel on a VPS

    Modern open-source game server management platform — the spiritual successor to Pterodactyl with a polished UI and Wings daemon.

    Prerequisites

    • 2 vCPU cores minimum (4 recommended if co-locating Wings)
    • 2 GB RAM minimum for the panel (4 GB+ if running Wings on the same server)
    • 20 GB SSD storage minimum
    • Ubuntu 22.04 LTS
    • A domain or subdomain pointed at your VPS IP
    • Root or sudo access

    Architecture note: The panel and Wings (the daemon that runs game servers) are separate components. For production, run Wings on a dedicated node. This guide covers both panel installation and Wings setup.

    1

    Prepare the Server

    Update the system
    apt update && apt upgrade -y
    Install base dependencies
    apt install -y curl wget git unzip tar software-properties-common

    Install PHP 8.3

    Add PHP repository and install
    add-apt-repository ppa:ondrej/php -y
    apt update
    apt install -y php8.3 php8.3-fpm php8.3-cli php8.3-mysql php8.3-pgsql \
      php8.3-mbstring php8.3-tokenizer php8.3-bcmath php8.3-xml php8.3-curl \
      php8.3-zip php8.3-gd php8.3-intl php8.3-redis

    Install Composer

    Install Composer
    curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
    composer --version

    Install MariaDB

    Install and secure MariaDB
    apt install -y mariadb-server
    systemctl enable mariadb
    systemctl start mariadb
    mysql_secure_installation

    Install Redis & Nginx

    Install Redis and Nginx
    apt install -y redis-server
    systemctl enable redis-server
    systemctl start redis-server
    
    apt install -y nginx
    systemctl enable nginx
    systemctl start nginx
    2

    Create the Database

    Create database and user
    mysql -u root -p
    SQL commands
    CREATE DATABASE pelican;
    CREATE USER 'pelican'@'127.0.0.1' IDENTIFIED BY 'your_strong_password_here';
    GRANT ALL PRIVILEGES ON pelican.* TO 'pelican'@'127.0.0.1';
    FLUSH PRIVILEGES;
    EXIT;
    3

    Download and Install Pelican Panel

    Download and extract
    mkdir -p /var/www/pelican
    cd /var/www/pelican
    curl -Lo panel.tar.gz https://github.com/pelican-dev/panel/releases/latest/download/panel.tar.gz
    tar -xzvf panel.tar.gz
    chmod -R 755 storage/* bootstrap/cache/
    Install dependencies
    composer install --no-dev --optimize-autoloader
    Setup environment
    cp .env.example .env
    php artisan key:generate --force
    4

    Configure the Environment

    Edit .env
    nano .env
    .env configuration
    APP_URL=https://panel.yourdomain.com
    APP_TIMEZONE=UTC
    
    DB_HOST=127.0.0.1
    DB_PORT=3306
    DB_DATABASE=pelican
    DB_USERNAME=pelican
    DB_PASSWORD=your_strong_password_here
    
    CACHE_DRIVER=redis
    SESSION_DRIVER=redis
    QUEUE_CONNECTION=redis
    
    REDIS_HOST=127.0.0.1
    REDIS_PORT=6379
    Run migrations and set ownership
    php artisan migrate --seed --force
    chown -R www-data:www-data /var/www/pelican
    5

    Configure Nginx

    Create Nginx config
    rm /etc/nginx/sites-enabled/default
    nano /etc/nginx/sites-available/pelican
    /etc/nginx/sites-available/pelican
    server {
        listen 80;
        server_name panel.yourdomain.com;
        return 301 https://$server_name$request_uri;
    }
    
    server {
        listen 443 ssl http2;
        server_name panel.yourdomain.com;
    
        root /var/www/pelican/public;
        index index.php;
    
        access_log /var/log/nginx/pelican.access.log;
        error_log  /var/log/nginx/pelican.error.log error;
    
        client_max_body_size 100m;
        client_body_timeout 120s;
        sendfile off;
    
        ssl_certificate /etc/letsencrypt/live/panel.yourdomain.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/panel.yourdomain.com/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;
    
        add_header X-Content-Type-Options nosniff;
        add_header X-XSS-Protection "1; mode=block";
        add_header X-Robots-Tag none;
        add_header Content-Security-Policy "frame-ancestors 'self'";
        add_header X-Frame-Options DENY;
        add_header Referrer-Policy same-origin;
    
        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 site
    ln -s /etc/nginx/sites-available/pelican /etc/nginx/sites-enabled/
    6

    Issue an SSL Certificate

    Install Certbot and issue certificate
    apt install -y certbot python3-certbot-nginx
    certbot certonly --nginx -d panel.yourdomain.com
    Test and reload Nginx
    nginx -t
    systemctl reload nginx
    7

    Configure the Queue Worker

    Pelican uses Laravel's queue system for background tasks. Create a systemd service:

    /etc/systemd/system/pelican.service
    [Unit]
    Description=Pelican Panel Queue Worker
    After=redis-server.service
    
    [Service]
    User=www-data
    Group=www-data
    Restart=always
    ExecStart=/usr/bin/php /var/www/pelican/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
    systemctl enable --now pelican.service
    systemctl status pelican.service
    8

    Set Up the Cron Job

    Add cron job
    crontab -e -u www-data
    Cron entry
    * * * * * php /var/www/pelican/artisan schedule:run >> /dev/null 2>&1
    9

    Create the Admin User

    Create admin
    php artisan p:user:make

    You will be prompted for email, username, name, password, and whether the user should be an admin (enter yes).

    10

    Log In and Configure the Panel

    Navigate to https://panel.yourdomain.com and log in with your admin credentials.

    Create a Location

    Go to Admin → Locations → Create New. Give it a short name (e.g., us-east).

    Create a Node

    Go to Admin → Nodes → Create New. Set the FQDN, memory, disk limits, and daemon port. After saving, click the Configuration tab to get the Wings YAML.

    11

    Install Wings (Game Server Daemon)

    Wings runs on the node that hosts your game servers. This can be the same VPS or a separate one.

    Install Docker

    Install Docker
    curl -sSL https://get.docker.com/ | CHANNEL=stable bash
    systemctl enable --now docker

    Download Wings

    Download and install Wings
    mkdir -p /etc/pelican
    curl -L -o /usr/local/bin/wings "https://github.com/pelican-dev/wings/releases/latest/download/wings_linux_amd64"
    chmod u+x /usr/local/bin/wings

    Configure Wings

    Copy the configuration YAML from the panel's node Configuration tab:

    Paste Wings config
    nano /etc/pelican/config.yml

    Create Wings systemd service

    /etc/systemd/system/wings.service
    [Unit]
    Description=Pelican Wings Daemon
    After=docker.service
    Requires=docker.service
    PartOf=docker.service
    
    [Service]
    User=root
    WorkingDirectory=/etc/pelican
    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
    systemctl status wings

    In the panel, refresh the node page. The status indicator should turn green.

    12

    Open Required Firewall Ports

    Panel server

    Panel UFW rules
    ufw allow 80/tcp
    ufw allow 443/tcp
    ufw enable

    Wings node

    Wings UFW rules
    ufw allow 80/tcp
    ufw allow 443/tcp
    ufw allow 8080/tcp   # Wings daemon (use 443 if configured for SSL)
    ufw allow 2022/tcp   # SFTP for file management
    ufw enable

    Game server ports

    Open game port range
    ufw allow 25565:25575/tcp
    ufw allow 25565:25575/udp

    Troubleshooting

    Panel shows 500 error

    Check Laravel logs
    tail -n 50 /var/www/pelican/storage/logs/laravel.log

    Queue worker is not running

    Check service
    systemctl status pelican.service
    journalctl -u pelican.service -n 50

    Wings node shows offline

    Verify Wings is running, the FQDN resolves correctly, and required ports are open.

    Check Wings
    systemctl status wings

    Permission errors

    Fix permissions
    chown -R www-data:www-data /var/www/pelican
    chmod -R 755 /var/www/pelican/storage /var/www/pelican/bootstrap/cache

    Certbot fails

    Ensure DNS A record is pointing to your VPS IP:

    Check DNS
    dig +short panel.yourdomain.com