
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
| What | Where (default) | Why it matters |
|---|---|---|
| Server files | /var/lib/pterodactyl/volumes/<server uuid> | Worlds, configs, plugins |
| SFTP host key | /var/lib/pterodactyl/volumes/.sftp/id_ed25519 | Else SFTP clients warn of a changed key |
| Local backups | /var/lib/pterodactyl/backups/<backup uuid>.tar.gz | Archives from the default wings backup driver |
| Server states | /var/lib/pterodactyl/states.json | Servers marked running start when Wings boots |
| Wings config | /etc/pterodactyl/config.yml | Node 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 folders | The paths under allowed_mounts in config.yml | Only if you use Mounts |
| Nodes, allocations, servers | The panel's database | Stays 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 Server | Copy the node | |
|---|---|---|
| Work | One transfer per server, in the admin area | One copy for the whole node |
| Downtime | Each server, during its own transfer | All servers, during the final copy |
| Node address | A second node with its own FQDN | Same FQDN, new IP |
| Allocations | Chosen per server on the new node | Same ports, moved to the new IP |
| Local backups | Stay on the old node | Come along |
| SFTP host key | New name, new key | Unchanged |
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 wingson 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 see | Likely cause | Fix |
|---|---|---|
| Transfer Server is grey: "Transferring a server requires more than one node to be configured on your panel." | Only one node | Add 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 limits | Raise Total Memory, Disk Space or Overallocate on its Settings tab |
Transfer has failed. in the console | The old node can't reach the new one, or the certificate or checksum failed | Rerun the curl test on the old node; read sudo journalctl -u wings on both |
A server won't start: cannot assign requested address | Its allocation still names the old IP | Move the allocation as above |
| Red heart on the Nodes page | DNS, certificate, ports or Cloudflare | Our Wings node offline guide |
| SFTP clients warn that the host key changed | .sftp/id_ed25519 didn't come along | Step 9 of our SFTP guide |
| Servers can't download anything | dns under docker, network in config.yml lists the old host's resolvers | Use 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:
- Pterodactyl docs: Installing Wings, Wings configuration, Upgrading Wings, SSL certificates, Troubleshooting, Getting Started
- Panel 1.15.2 source: server Manage tab, admin ServerTransferController.php, remote ServerTransferController.php, DaemonTransferRepository.php, Node.php, Server.php, Allocation.php, allocation index migration, AssignmentService.php, NodesController.php, BuildModificationService.php, ServersController.php, NodeUpdateService.php, NodeDeletionService.php, DownloadLinkService.php, BackupController.php, ServerTransformer.php, AuthenticateServerAccess.php, SftpAuthenticationController.php, node form, node Settings tab, node Configuration tab, node About page, node Allocation tab, Build Configuration, database host form, ConflictStateRenderer.tsx, Console.tsx, admin messages, exception messages, admin routes, application API routes, client API routes, releases
- Wings 1.13.4 source: router_server_transfer.go, router_transfer.go, transfer/source.go, transfer/archive.go, transfer/transfer.go, router_server.go, server/power.go, docker/power.go, docker/container.go, allocations.go, config.go, config_docker.go, cmd/root.go, manager.go, sftp/server.go, backup.go, middleware.go, CHANGELOG.md, releases
- Docker: Install on Ubuntu, Install on Debian, install script, docker container ls, Moby source: mapper_linux.go, port_mapping_linux.go
- Go: Linux error strings; Linux: bind(2)
- Certbot: user guide
- MariaDB: mariadb-dump, mariadb client
- systemd: systemctl, journalctl
- Man pages: rsync(1), du(1), df(1), getent(1), crontab(1), ufw(8), ss(8), curl