Move Pterodactyl Wings to a New Server Without Losing Data

Published on

Move a Pterodactyl Wings node to a new VPS: transfer servers in the panel or copy volumes and config.yml with rsync, then fix DNS, certificates and allocations.

A VPS control panel listing one Debian server with its memory, cores, disk and an offline status

Your Wings node needs a new home: a bigger VPS, newer hardware or another provider. The panel stays put, but the game servers, their files and the node's address have to move without anyone losing a world. You can transfer servers one by one to a second node, or copy the whole node and keep its node entry. Below are both, with commands for Ubuntu 24.04 and Debian 12, checked against the source of Panel 1.15.2 and Wings 1.13.4, the current releases on 30 October 2026.

Quick answer: For a few servers, add the new VPS as a second node and use Transfer Server on each server's Manage tab: the old node streams the files to the new one. For a whole node, keep its node entry: rsync /var/lib/pterodactyl, /etc/pterodactyl and /etc/letsencrypt to the new VPS while the servers run, stop the servers and Wings, rsync again with --delete, point the node's FQDN and allocations at the new IP, and start Wings there. Keep the old VPS until everything works.

What Has to Move

WhatWhere (default)Why it matters
Server files/var/lib/pterodactyl/volumes/<server uuid>Worlds, configs, plugins
SFTP host key/var/lib/pterodactyl/volumes/.sftp/id_ed25519Else SFTP clients warn of a changed key
Local backups/var/lib/pterodactyl/backups/<backup uuid>.tar.gzArchives from the default wings backup driver
Server states/var/lib/pterodactyl/states.jsonServers marked running start when Wings boots
Wings config/etc/pterodactyl/config.ymlNode token, ports, paths and every setting you tuned
Certificate/etc/letsencrypt/live/<node FQDN>/Issued for the name, so it works on a new IP
Mount foldersThe paths under allowed_mounts in config.ymlOnly if you use Mounts
Nodes, allocations, serversThe panel's databaseStays on the panel host

Containers and images stay behind: before every start, Wings recreates the server's container from the panel's data and pulls its image (power.go, container.go). A database host (Admin, Databases) on the old VPS moves too, and configs that name its IP need the new one.

Transfer or Copy: Which Fits

Transfer ServerCopy the node
WorkOne transfer per server, in the admin areaOne copy for the whole node
DowntimeEach server, during its own transferAll servers, during the final copy
Node addressA second node with its own FQDNSame FQDN, new IP
AllocationsChosen per server on the new nodeSame ports, moved to the new IP
Local backupsStay on the old nodeCome along
SFTP host keyNew name, new keyUnchanged

Transfers suit moving some servers; a copy retires the whole node. The Transfer Server box itself warns: "This feature has not been fully tested and may have bugs." Try it on an unimportant server first.

Step 1: Prepare the New VPS

On the old node, check the size of what you'll copy and the Wings release:

sudo du -sh /var/lib/pterodactyl/volumes /var/lib/pterodactyl/backups
sudo wings version

df -h /var/lib on the new VPS should show more free space. Run the same release on both, updating the old node first if needed with the upgrade guide; running servers "will not be affected". A Space-Node VPS is KVM with full root access, which the Wings install guide calls "guaranteed to work", with Ubuntu 24.04 LTS and Debian on the order form.

On the new VPS, run the install guide's commands with sudo, plus Certbot and rsync:

curl -sSL https://get.docker.com/ | sudo 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
sudo apt update && sudo apt install -y certbot rsync

The script installs the latest stable Docker. Docker's Ubuntu and Debian pages prefer their apt repository for production. Install rsync on the old node too, and don't start Wings yet.

Both ways copy files as root from the old node, so give its root an SSH key for the new VPS, as in Step 3 of our website move guide. The commands below use /root/.ssh/migrate and the new IP 198.51.100.20.

Way 1: Transfer Servers to a New Node

Add the New VPS as a Node

Point a new name such as node2.example.com at the new VPS, DNS only on Cloudflare (our Wings node offline guide explains why). With UFW on, open ports 80, 8080 and 2022 (sudo ufw allow 80/tcp and so on), then get the certificate:

sudo certbot certonly --standalone -d node2.example.com

In the admin area, open Nodes, Create New, and enter that FQDN, Use SSL Connection, memory, disk and the daemon ports (8080 and 2022 by default). Save the node's Configuration tab as /etc/pterodactyl/config.yml, or run the wings configure command from Generate Token. Copy /etc/systemd/system/wings.service from the old node, then:

sudo systemctl enable --now wings

enable reloads systemd and --now starts the unit (systemctl). When the node's heart turns green, add allocations on its Allocation tab: the IP from hostname -I | awk '{print $1}' and the ports you need (the panel takes ports above 1024).

Transfers go from node to node: the old node's Wings uploads to https://node2.example.com:8080/api/transfers (DaemonTransferRepository.php). Test that connection from the old node:

curl -i -m 10 https://node2.example.com:8080/api/system

A 401 with The required authorization heads were not present in the request. (the typo is Wings' own) means the port is open and the certificate checks out.

Transfer Each Server

Stop the server first: the old node waits only 15 seconds for a running server to stop, and otherwise the transfer doesn't start (router_server_transfer.go). Then open Admin, Servers, the server, Manage, click Transfer Server, choose the Node, a Default Allocation and any Additional Allocation(s), and click Confirm. The panel first checks the new node's memory and disk limits (Node.php).

Then, per the source:

  • The old node streams the server's folder as a gzipped tar to the new node, which unpacks it on arrival and checks a SHA-256 checksum (source.go, router_transfer.go). Since Wings 1.11.0, transfers "no longer buffer to disk" (changelog), so neither node needs room for an archive.
  • Admins see [Transfer System] [Source Node] progress lines every 5 seconds in the server's console. Users see "Your server is being transferred to a new node, please check back later."
  • On success, the panel assigns the server to the new node and allocation, frees the old allocations and has the old node delete the server's files (ServerTransferController.php). The server stays stopped, so start it yourself. On failure, the console prints Transfer has failed., the new node removes what it received, and the server stays on the old node.

Bring the Local Backups Along

A transfer moves the server's folder only. Archives from the default wings backup driver stay in /var/lib/pterodactyl/backups on the old node, while the panel sends downloads and restores to the server's current node (DownloadLinkService.php, BackupController.php). Each file is named after its backup's UUID, so after your transfers, copy the folder as it is:

sudo rsync -a -e "ssh -i /root/.ssh/migrate" /var/lib/pterodactyl/backups/ root@198.51.100.20:/var/lib/pterodactyl/backups/

S3 backups need nothing, as the panel signs their download links for the bucket. Once the old node is empty, you can delete it on its About page.

Way 2: Copy the Whole Node

Keep the node's FQDN, here node1.example.com, so the certificate, your users' saved SFTP address and the node's panel settings stay valid. A day ahead, lower the TTL of its A record, as in Step 2 of the website move guide.

First Copy While the Servers Run

On the old node:

NEW=198.51.100.20
SSH='ssh -i /root/.ssh/migrate'
sudo rsync -a --info=progress2 -e "$SSH" /var/lib/pterodactyl/ root@$NEW:/var/lib/pterodactyl/
sudo rsync -a -e "$SSH" /etc/pterodactyl/ root@$NEW:/etc/pterodactyl/
sudo rsync -a -e "$SSH" /etc/letsencrypt/ root@$NEW:/etc/letsencrypt/
sudo rsync -a -e "$SSH" /etc/systemd/system/wings.service root@$NEW:/etc/systemd/system/

-a keeps owners, permissions, times and the symlinks in /etc/letsencrypt, and later runs only send the differences (rsync). Keep this shell open.

Don't start Wings on the new VPS yet. It holds the same node token, and at boot it starts every server that states.json marks as running (root.go), which would give you second copies of live servers.

Stop Everything and Copy Again

Stop every server in the panel, so each gets its own stop command. Then set Maintenance Mode to Enabled on the node's Settings tab: users see "The node of this server is currently under maintenance.", and the panel refuses power actions, the console and SFTP logins on that node, admins included (AuthenticateServerAccess.php). On the old node, check that no server container runs, then stop Wings for good:

sudo docker ps --filter label=ContainerType=server_process
sudo systemctl disable --now wings

Wings labels server containers that way, so the list should be empty. Stopping Wings saves each server's state, now offline, to states.json. Copy again, now with --delete to remove files deleted since the first copy:

sudo rsync -a --delete --info=progress2 -e "$SSH" /var/lib/pterodactyl/ root@$NEW:/var/lib/pterodactyl/
sudo rsync -a -e "$SSH" /etc/pterodactyl/ root@$NEW:/etc/pterodactyl/

Point the FQDN and the Allocations at the New IP

Change the node's A record to the new IP. Then the allocations: each stores an IP, and Wings publishes every port as TCP and UDP on exactly that IP (allocations.go). Docker binds those addresses (mapper_linux.go), and Linux refuses to bind an address the machine doesn't have (EADDRNOTAVAIL in bind(2)), so a server still on the old IP fails to start with cannot assign requested address.

For a few servers, add the same ports on the new IP on the node's Allocation tab. Then, in each server's Build Configuration, select the new allocation under Assign Additional Ports and the old one under Remove Additional Ports, and click Update Build Configuration. Removing the Game Port makes the first new allocation the Game Port (BuildModificationService.php).

For many servers, one SQL statement on the panel host does it, after a dump. The node's ID is in its admin address, as in /admin/nodes/view/1:

sudo mariadb-dump --single-transaction panel > panel-before-move.sql
sudo mariadb panel -e "UPDATE allocations SET ip = '198.51.100.20' WHERE node_id = 1 AND ip = '203.0.113.10';"

On MySQL, use mysqldump and mysql. Each IP and port may exist only once per node (migration), so first delete unused allocations you already added on the new IP, with the red minus icon in the IP Address heading of the Allocation tab. Wings fetches a server's configuration before every start (power.go), so the change applies at the next start. Also fix IP aliases that name the old address: users see those instead of the IP.

Start Wings on the New VPS

With UFW on, open ports 80, 8080 and 2022 on the new VPS first, as in Way 1. When getent hosts node1.example.com on the panel host returns the new IP, start Wings on the new VPS and read its log:

sudo systemctl enable --now wings
sudo journalctl -u wings -n 50 --no-pager

Set Maintenance Mode to Disabled and start the servers. First starts take longer: Docker pulls the image, and Wings sets the files' owner to its pterodactyl user, whose user ID may differ on the new VPS (check_permissions_on_boot, on by default per the configuration page).

Then test renewal of the copied certificate; standalone mode needs port 80 open:

sudo certbot renew --dry-run

If the old node renewed through root's crontab (sudo crontab -l), add that line on the new VPS.

Checks After the Move

  • The node's heart is green, and its About page shows the Wings version.
  • sudo ss -ltnp | grep wings on the new VPS shows ports 8080 and 2022.
  • Each server starts, and players can join on the new address.
  • SFTP works with the address in the server's Settings tab, built from the node's FQDN (ServerTransformer.php).
  • Keep the old VPS for a week, Wings disabled, as your way back.

If It Still Fails

What you seeLikely causeFix
Transfer Server is grey: "Transferring a server requires more than one node to be configured on your panel."Only one nodeAdd the new node first
"The node you selected does not have the required disk space or memory available to accommodate this server."The new node's limitsRaise Total Memory, Disk Space or Overallocate on its Settings tab
Transfer has failed. in the consoleThe old node can't reach the new one, or the certificate or checksum failedRerun the curl test on the old node; read sudo journalctl -u wings on both
A server won't start: cannot assign requested addressIts allocation still names the old IPMove the allocation as above
Red heart on the Nodes pageDNS, certificate, ports or CloudflareOur Wings node offline guide
SFTP clients warn that the host key changed.sftp/id_ed25519 didn't come alongStep 9 of our SFTP guide
Servers can't download anythingdns under docker, network in config.yml lists the old host's resolversUse those from resolvectl status (troubleshooting), restart Wings and the servers

FAQ

Can I transfer every server on a node at once? No. Transfer Server sits on each server's Manage tab, and Panel 1.15.2's application and client APIs have no transfer endpoint. To move a whole node at once, copy it (Way 2).

Do players need a new address? If they join with the IP the panel shows, yes: both ways change it, and a transfer can change the port too. Players who join through the node's FQDN notice nothing after a copy.

Can I move the panel at the same time? Move one part at a time and test in between. Moving the panel means restoring its database, its .env with APP_KEY and its files, as in our Pterodactyl backup guide.

How do I go back if something breaks? After a copy, stop Wings on the new VPS, point the A record back, reverse the allocation change and run sudo systemctl enable --now wings on the old node, then copy back what players changed meanwhile. After a transfer, transfer the server back.

Sources

All opened on 30 October 2026: