Skip to content
Current coupon:10% offUse it in your order

Pterodactyl Wings: adding a node, allocations and your first server

Install Wings and Docker, add a node in the Panel, set up the certificate, ports, allocations and firewall, and create your first game server. Every form field explained.

  • expert
  • ~60 min
  • Updated 2 Oct 2026

Wings is the Pterodactyl service that runs game servers in Docker containers on your server. We'll install it, connect it to the Panel, open the necessary ports and create the first server.

What you'll need

  • A working Pterodactyl Panel with HTTPS (guide)
  • A VPS for the game servers with Ubuntu 24.04 or Debian 13 (it can be the same VPS as the Panel)
  • A domain for the node: the same as the Panel (panel.example.cz) or its own (node.example.cz)
  • An SSH connection as root
  • About 60 minutes

How it works#

The Panel is just a web interface. The real work is done by Wings on a node (the server where the games run). Wings takes instructions from the Panel, downloads Docker images, runs game servers in isolated containers, keeps an eye on their RAM and disk, and handles the console and files.

What matters is who connects where:

ConnectionPortProtocolWho connects
Wings API8080TCP (HTTPS)The Panel and every user's browser (live console over websocket, file uploads). That's why the node's address must be publicly reachable and have a valid certificate.
SFTP2022TCPUsers uploading files with a program such as WinSCP or FileZilla.
Game portsdepends on the game, for example 25565TCP and UDPPlayers.

Game servers get the internal Docker network pterodactyl_nw. A network interface pterodactyl0 with the address 172.18.0.1 appears on the VPS; containers use it to reach the server itself (you'll use this for the database host). Server data lives in /var/lib/pterodactyl/volumes.

Checking virtualization#

Wings needs Docker, and Docker needs full virtualization. StormHost VPSs run on KVM, which works. You can check it with:

bash
systemd-detect-virt
Outputtext
kvm

A result of openvz or lxc would mean that Docker (and therefore Wings) most likely won't work.

Installing Docker#

Install Docker from Docker's official repository. Every command is explained in detail in the Docker and Docker Compose guide; here are just the steps:

Ubuntu 24.04

bash
apt update
apt -y install ca-certificates curl
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF
apt update
apt -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Debian 13

bash
apt update
apt -y install ca-certificates curl
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/debian
Suites: $(. /etc/os-release && echo "$VERSION_CODENAME")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF
apt update
apt -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Then enable Docker at boot and test it:

bash
systemctl enable --now docker
docker run --rm hello-world
  • systemctl enable --now docker – Docker starts right away and then at every VPS boot.
  • docker run --rm hello-world – downloads and runs a test container; --rm deletes it when it finishes. You'll see the text Hello from Docker!.

Skip the “Enabling Swap” step from the documentation

The official Wings documentation describes a GRUB change (swapaccount=1). It's only needed on kernels older than 6.1. Ubuntu 24.04 and Debian 13 have newer kernels (check with uname -r), so skip this step.

Downloading Wings#

bash
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
  • mkdir -p /etc/pterodactyl – a directory for the Wings configuration.
  • curl -L -o /usr/local/bin/wings "…" – downloads the latest Wings release as the program /usr/local/bin/wings. -L follows GitHub's redirects.
  • $([[ "$(uname -m)" == "x86_64" ]] && echo "amd64" || echo "arm64") – picks the right file for the CPU architecture: uname -m prints x86_64 (typical servers), for which the amd64 build is downloaded.
  • chmod u+x – lets the owner (root) run the file.

Check: wings version prints the version number.

Domain and certificate for the node#

The Panel runs on HTTPS, so Wings must use HTTPS too. Otherwise the browser would block the connection to the node. The certificate is tied to the node's domain (the FQDN field in the Panel).

Same VPS as the Panel

If Wings runs on the same VPS as the Panel, use the Panel's domain (panel.example.cz) as the node's FQDN. You already have the certificate from the Panel installation, and Wings finds it at /etc/letsencrypt/live/panel.example.cz/. Nothing else to do.

Separate VPS for the node

  1. Create an A record for node.example.cz with the node VPS's IPv4 address.

  2. Open port 80 (TCP) in the node's firewall; Let's Encrypt uses it to validate the domain. Keep it open afterwards too: every automatic certificate renewal goes through the same port.

  3. Install Certbot: apt -y install certbot.

  4. Get the certificate. A node VPS usually has no web server running, so use standalone mode, in which Certbot briefly runs its own server on port 80:

    bash
    certbot certonly --standalone -d node.example.cz
    • certonly – only gets the certificate.
    • --standalone – validation through Certbot's temporary server on port 80 (the port must not be taken by another program).
    • -d node.example.cz – the node's domain.

If Nginx runs on the node VPS, use --nginx instead of --standalone.

After a certificate renewal, Wings has to be restarted, otherwise it keeps using the old certificate. Create a deploy hook (a script Certbot runs after every successful renewal):

bash
cat > /etc/letsencrypt/renewal-hooks/deploy/restart-wings.sh <<'EOF'
#!/bin/sh
systemctl restart wings
EOF
chmod 755 /etc/letsencrypt/renewal-hooks/deploy/restart-wings.sh
  • Certbot runs files in the renewal-hooks/deploy directory after every certificate renewal.
  • systemctl restart wings – restarts Wings. This doesn't stop running game servers; Wings reconnects to them after it starts.
  • chmod 755 – the script has to be executable.

The node's domain must not go through the Cloudflare proxy

If you manage DNS in Cloudflare, keep the node domain's record set to DNS only (gray cloud). On port 8080 Cloudflare only passes unencrypted HTTP, and it doesn't let SFTP or game ports through its proxy at all. If the node uses the same domain as the Panel, keep the whole Panel domain on the gray cloud, or use a separate subdomain for the node.

Location#

Every node belongs to a location. A location is just a label for sorting nodes (for example by data center).

  1. In the Panel, open the admin area (gear icon in the top right) and click Locations on the left.
  2. Click Create New.
  3. Fill in Short Code, a short identifier of 1–⁠60 characters, for example cz-praha.
  4. Fill in Description, a description of the location for you and other admins, for example VPS in Prague.
  5. Click Create.

The node in the Panel#

In the admin area, click Nodes on the left and then Create New. Fill in the form according to the table:

FieldWhat to enterWhy, and when to choose differently
NameFor example node-praha-1A name for you. Letters without accents, digits, _, -, . and spaces are allowed.
DescriptionOptionalA note for you.
LocationThe location from the previous sectionJust a category.
Node VisibilityPublicPrivate prevents servers from being placed on the node automatically (auto-deploy). Keep Public for normal use.
FQDNpanel.example.cz (same VPS) or node.example.czThe address where the Panel and browsers find Wings. It must be a domain, not an IP address, if you use SSL.
Communicate Over SSLUse SSL ConnectionWhen the Panel runs on HTTPS, you can't select anything else.
Behind ProxyNot Behind ProxyBehind Proxy only if Wings sits behind a proxy that terminates TLS itself. Wings then doesn't look for a certificate. Not the case in this guide.
Daemon Server File Directory/var/lib/pterodactyl/volumesWhere game server data is stored. Only change it when working with a second disk.
Total Memory (MiB)The VPS's RAM minus a reserveHow much RAM the Panel may hand out to game servers. On an 8 GB VPS that also runs the Panel, enter for example 6144 (6 GB). 1 GB = 1024 MiB.
Memory Over-Allocation (%)0By how many percent the servers' total RAM may exceed Total Memory. 0 = never, -1 = turns the check off. Overcommitting RAM leads to server crashes.
Total Disk Space (MiB)Free disk space minus a reserveFor example, on a 100 GB disk enter 81920 (80 GB). Leave the rest for the system, Docker images and backups.
Disk Over-Allocation (%)0Same as for memory.
Daemon Port8080The Wings API port. Only change it if it conflicts with another program.
Daemon SFTP Port2022The SFTP port for game server files. Never enter 22; that belongs to the VPS's SSH server.

Click Create Node. The Panel opens the node's details.

How much RAM to leave for the system

You can find the VPS's total RAM in MiB with free -m (row Mem:, column total). The system, Docker and Wings need a few hundred MiB. If the Panel with MariaDB and Redis also runs on the VPS, leave them at least 1–⁠2 GB.

Configuring Wings#

In the node's details, open the Configuration tab. You can get the configuration onto the VPS in one of two ways.

Method A, automatic: Click Generate Token. The Panel shows a command starting with cd /etc/pterodactyl && sudo wings configure --panel-url https://panel.example.cz --token …. Copy all of it and run it on the node VPS. Wings downloads its configuration from the Panel.

Method B, manual:

  1. On the VPS, open the file:

    bash
    nano /etc/pterodactyl/config.yml
  2. Paste the whole block from the Configuration tab, save (Ctrl+O, Enter) and close (Ctrl+X).

What's in the configuration:

KeyWhat it means
uuidThe node's unique identifier in the Panel.
token_id, tokenThe secret key Wings and the Panel use to authenticate each other. Whoever has it controls the node. Don't share it or post it in chats or forums.
api.host0.0.0.0 = the API listens on all VPS addresses.
api.portThe Daemon Port from the form (8080).
api.ssl.enabledtrue if the node uses SSL and isn't behind a proxy.
api.ssl.cert, api.ssl.keyThe certificate path based on the FQDN, for example /etc/letsencrypt/live/panel.example.cz/fullchain.pem.
api.upload_limitThe largest file (in MB) that can be uploaded through the Panel's file manager. You change it in the node settings.
system.dataThe directory with server data.
system.sftp.bind_portThe SFTP port (2022).
remoteThe Panel address Wings reports to.

On the first start, Wings adds further default values to the file, for example the Docker network settings (docker.network, address 172.18.0.1) and DNS servers for containers (1.1.1.1, 1.0.0.1).

First start in debug mode#

Before running it in the background, try Wings by hand so you can see any errors:

bash
wings --debug
  • --debug – a detailed log of everything Wings does.

On the first start, Wings creates the Docker network (creating missing pterodactyl0 interface…) and reports that it's listening (configuring internal webserver). Then open Nodes in the Panel. The node shows a green pulsing heart = the Panel has connected to Wings. A red heart means the connection isn't working (see Troubleshooting).

Once the heart is green, stop Wings with Ctrl+C.

Wings as a service#

To keep Wings running permanently and start it automatically after a VPS reboot, create a systemd service:

bash
nano /etc/systemd/system/wings.service
/etc/systemd/system/wings.serviceini
[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
LineWhat it does
After=docker.serviceWings starts only after Docker.
Requires=docker.serviceWings won't start without a running Docker.
PartOf=docker.serviceRestarting or stopping Docker carries over to Wings.
User=rootWings needs root privileges (it controls Docker and the server files).
WorkingDirectory=/etc/pterodactylThe working directory with config.yml.
LimitNOFILE=4096How many files and connections Wings may have open at once.
PIDFile=Where Wings writes its process ID.
ExecStart=/usr/local/bin/wingsStarts the program (without --debug).
Restart=on-failureWings starts again after a crash.
StartLimitInterval=180, StartLimitBurst=30Protection against an endless restart loop: at most 30 starts in 180 seconds.
RestartSec=5sWaits 5 seconds before restarting.
WantedBy=multi-user.targetStarts at VPS boot.

Enable and start the service:

bash
systemctl enable --now wings
systemctl status wings

You'll see Active: active (running). The node's heart in the Panel stays green.

Allocations#

An allocation is a combination of an IP address and a port that a game server gets. Every server needs at least one (the primary one); you can add more for RCON, query or plugins.

  1. Find the VPS's public IPv4 address. You'll find it in the customer area in the Network tab, or this prints it:

    bash
    hostname -I | awk '{print $1}'
    • hostname -I – prints all IP addresses of the VPS; awk '{print $1}' takes the first one.
  2. In the node's details, open the Allocation tab.

  3. On the right, under Assign New Allocations, fill in the fields according to the table and click Submit.

FieldWhat to enterWhy
IP AddressThe VPS's public IPv4 address, for example 203.0.113.10The address the servers will listen on. Don't use 127.0.0.1; players can't connect to it.
IP AliasOptionally a domain, for example mc.example.czText the Panel shows to users instead of the IP address. It has no effect on routing; you have to point the domain in DNS.
PortsSingle ports or ranges separated by commas, for example 25565-25574Ports must be above 1024 and at most 65535; one range can have at most 1000 ports.

Typical default ports: Minecraft Java 25565, Rust 28015 (and 28016 for RCON), FiveM 30120. For several servers of the same game, add a range; each server gets a different port.

Firewall#

Open the ports in the firewall in the customer area (guide: Firewall in the customer area). If inbound traffic is set to Block everything except allowed, add Inbound · Allow rules:

ProtocolPortWhat for
TCP8080Wings API (the Panel and users' browsers)
TCP2022SFTP
TCPallocation range, for example 25565:25574Game servers
UDPallocation range, for example 25565:25574Game servers and query

Port ranges are written differently

In the Pterodactyl Panel, a range is written with a dash (25565-25574); in the customer area firewall, with a colon (25565:25574).

If you use UFW on the VPS, allow the API and SFTP in it:

bash
ufw allow 8080/tcp
ufw allow 2022/tcp

You don't need to allow game ports in UFW. Docker publishes container ports with its own rules that bypass UFW (details in the UFW firewall guide). So restrict game ports with the firewall in the customer area; it sits in front of the VPS and applies to everything.

First server#

  1. In the admin area, click Servers and then Create New.
  2. Fill in the form according to the table and click Create Server at the bottom.
FieldWhat to enterWhy
Server NameFor example SurvivalThe server's name in the Panel.
Server OwnerThe email of an existing Panel userWho will manage the server. You create users under Users.
Server DescriptionOptionalA description for you.
Start Server when InstalledcheckedThe server starts by itself after installation.
NodeYour nodeWhere the server will run.
Default AllocationA free allocation, for example 203.0.113.10:25565The server's primary IP and port.
Additional Allocation(s)Optionally more portsFor example for RCON or query.
Database Limit0 to 2How many databases the user may create themselves. Only works once a database host is set up.
Allocation Limit0 to 2How many extra ports the user may add themselves.
Backup LimitFor example 2How many backups the user may create in the Panel. Backups are stored on the node's disk (/var/lib/pterodactyl/backups) and take up space.
CPU Limit (%)For example 200100 = one CPU thread, 200 = two. 0 = unlimited (the server can max out the whole CPU and slow down the others).
CPU PinningemptyPinning to specific cores, for advanced users only.
Memory (MiB)For example 4096How much RAM the container gets. 0 = unlimited, which we don't recommend.
Swap (MiB)00 turns off swap for the container, -1 allows unlimited swap. A game server in swap is slow.
Disk Space (MiB)For example 20480The space limit. When a running server exceeds it, Wings stops it safely. 0 = no limit.
Block IO Weight500 (default)Disk priority relative to other containers (10–⁠1000).
Enable OOM Killerleave uncheckedChecked = the server process is killed when it exceeds its RAM. Unchecked = the process isn't killed but may freeze.
Game selection (two menus one below the other)For example Minecraft and then PaperThe first menu is the game category, the second the specific server type.
Skip … Install Scriptleave uncheckedThe install script downloads the game files. You only want to skip it for custom installations.
Docker ImageFor example Java 21The environment the server runs in. For Minecraft, the Java version must match the game version (see the tip below).
Startup CommandkeepThe start command, prefilled for the game.
Service VariablesFor example Minecraft Version latest, Build Number latestInstallation and startup settings for the game.

Java version for Minecraft

Minecraft up to 1.16.5 needs Java 8, 1.17 needs Java 16, 1.18 to 1.20.4 need Java 17, 1.20.5 to 1.21.x need Java 21 and 26.x needs Java 25. If the server starts with an UnsupportedClassVersionError, change the Docker Image in the server settings to a newer Java.

  1. Wings downloads the Docker image and starts the installation. Follow the progress in the server console: click the Panel name in the top left (this takes you from the admin area to the server overview) and open the new server. If the server belongs to another user, switch the Showing your servers toggle in the overview to Showing others' servers.
  2. For Minecraft, an Accept Minecraft® EULA window appears after the first start. Clicking I Accept means you agree to the Minecraft license terms, and the server starts.

Verification#

  • The node in Nodes shows a green heart.
  • After installation the server runs and you can see its output in the console (for Minecraft, the line Done (…)! For help, type "help").
  • In the game you can connect to 203.0.113.10:25565 (or to the IP Alias).
  • Over SFTP you can connect to the node's address and port 2022 (for example sftp://panel.example.cz:2022). You'll find the address and username in the server's Settings tab under SFTP Details (Server Address, Username). The password is the same as your Panel password.

Check on the VPS:

bash
systemctl is-active docker wings
docker ps
  • docker ps – lists running containers; each game server is one container.

Updating Wings#

Always update Wings after updating the Panel (Panel steps):

bash
systemctl stop wings
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
systemctl restart wings
  • systemctl stop wings – stops Wings so the program can be overwritten. Running game servers aren't affected.
  • curl … and chmod … – the same as during installation; they download the latest version.
  • systemctl restart wings – starts the new version; open connections reconnect on their own.

Troubleshooting#

Red heart on the node#

The Panel couldn't reach Wings. Work through the causes from the most common:

  1. Is Wings running? systemctl status wings. If not, run wings --debug and read the error.
  2. Is port 8080 open in the customer area firewall and in UFW?
  3. Does the node's FQDN point to the right IP? getent hosts node.example.cz.
  4. Does the certificate work? On the Panel VPS, run curl https://node.example.cz:8080. The response {"error":"The required authorization heads were not present in the request."} is fine: Wings is answering, you just didn't send a login token. A certificate error (SSL certificate problem) means a wrong or expired certificate.
  5. Is the node's domain going through the Cloudflare proxy (orange cloud)? Switch it to DNS only.
  6. Does config.yml match what the Configuration tab in the Panel shows? Deleting and recreating a node changes the token.
  7. Check that a browser extension such as AdBlock isn't blocking the connection.

failed to configure HTTPS server#

Wings didn't find the certificate. The output usually also contains no such file or directory with a path. The path in config.yml (api.ssl.cert) must match the certificate you have (certbot certificates). If you changed the node's FQDN, get a certificate for the new domain too.

address already in use#

Port 8080 or 2022 is already used by another program. Find out which one:

bash
ss -tulpn | grep -E ':8080|:2022'
  • ss -tulpn – lists listening ports (TCP and UDP) and the programs holding them.

Move the program elsewhere, or change the Daemon Port in the node settings, copy the new configuration and restart Wings.

The server console doesn't connect#

The browser shows Failed to connect to websocket instance after multiple attempts: try refreshing the page. The browser couldn't reach FQDN:8080. The causes are the same as for the red heart, but port 8080 also has to work from your computer, not just from the Panel. Open https://node.example.cz:8080 in your browser. If the page doesn't load, the problem is in the firewall, DNS or certificate.

Server installation fails while downloading#

The installation console shows messages like Could not resolve host. The containers don't have working DNS. By default Wings gives them the servers 1.1.1.1 and 1.0.0.1. Find the VPS's DNS servers with resolvectl status (the DNS Servers lines), or, if the command doesn't exist on Debian, in /etc/resolv.conf (the nameserver lines). Write them into /etc/pterodactyl/config.yml in place of the defaults (under docker: › network: › dns:). Don't use 127.0.0.53; it only works on the VPS itself, not inside a container. Then restart Wings: systemctl restart wings.

The server isn't created, the Panel reports a lack of space or memory#

The total RAM or disk of the servers would exceed the node's Total Memory or Total Disk Space. Raise the values in the node settings (the Settings tab) if the VPS really has the capacity, or lower the servers' limits.

The server shuts itself down after a while#

It exceeded its disk limit (Wings stops it safely) or flooded the console with output (flood protection). Check the server's disk usage in the Panel and the console output before the shutdown.

Summary

  • Wings runs as the wings service; server data is in /var/lib/pterodactyl/volumes.
  • The node needs a domain with a valid certificate and port 8080 reachable from the internet; the domain must not go through the Cloudflare proxy.
  • SFTP runs on port 2022, never on 22.
  • Allocation = public IP + port; in the Panel a range uses a dash, in the customer area firewall a colon.
  • Docker opens game ports outside UFW; restrict them with the firewall in the customer area.
  • After updating the Panel, update Wings too.

Search the guides