You might need to clone a server to move to a new location or plan, create a staging copy of production, or build a second server for load balancing. There are two main approaches: rebuild the new server, and copy the data (cleaner), or copy the whole system with rsync (faster when the setup isn’t documented). Here’s how to do both safely.
Option 1 (recommended): rebuild + copy data
- Create the new VPS with the same OS and version. See check the Linux version.
- Install the same software, ideally with an Ansible playbook or setup script. See Linux configuration management.
- Copy configuration selectively (
/etc/nginx,/etc/php, app.envfiles, systemd units, crontabs). - Copy data: website files, uploads, Docker volumes, and database dumps (not raw data files from a running database).
- Test, then switch traffic.
This gives you a clean system, with no leftovers, and documents your setup as you go. See move a website to a VPS.
Option 2: full system copy with rsync
When the server has years of undocumented changes, copying the whole filesystem can be the pragmatic choice. Requirements: the same distribution and version on both servers, and similar architectures (both x86-64).
- Install the same OS on the new VPS, and update both servers to the same package versions.
- Stop write-heavy services on the source (databases), or dump them, to get a consistent copy.
- From the new server, pull everything except system-specific paths:
sudo rsync -aAXHv --numeric-ids --delete \
--exclude={"/dev/*","/proc/*","/sys/*","/run/*","/tmp/*","/mnt/*","/media/*","/lost+found"} \
--exclude={"/boot/*","/etc/fstab","/etc/network/*","/etc/netplan/*","/etc/hostname","/etc/hosts"} \
--exclude={"/etc/machine-id","/etc/ssh/ssh_host_*","/var/lib/cloud/*","/swapfile"} \
root@old-server:/ /
-aAXHkeeps permissions, ACLs, extended attributes and hard links.--numeric-idspreserves UID/GID numbers.- Excluding
/boot,fstaband network config keeps the new server’s kernel, disk layout and network settings, so it still boots and stays reachable.
See rsync examples.
- Reboot the new server (keep the VNC console handy). See VPS VNC console.
Fix identity after cloning
A clone must not look identical to the original:
| Item | Fix |
|---|---|
| Hostname | hostnamectl set-hostname web2. See change the hostname |
/etc/machine-id |
If copied: rm /etc/machine-id && systemd-machine-id-setup |
| SSH host keys | If copied: rm /etc/ssh/ssh_host_* && ssh-keygen -A && systemctl restart ssh |
| IP addresses in configs | Search /etc and app configs for the old IP: grep -r "203.0.113.10" /etc /var/www |
| TLS certificates | Re-issue with Certbot after DNS points to the new server |
| Cron jobs | Disable jobs that must run only once (e.g. backups sending to the same target, billing tasks) |
| Monitoring and backup agents | Register the new host separately |
Duplicate machine IDs and host keys confuse logging, DHCP, monitoring, and SSH clients.
Databases
Never copy a running database’s data directory and expect it to be consistent. Instead:
- dump and restore (
mysqldump,pg_dump). See mysqldump and pg_dump; - or stop the database during the final rsync;
- or set up replication, for a near-zero-downtime switch. See database replication explained.
Test before cutover
- Use a hosts-file override to browse the site on the new server.
- Check logs (
journalctl -p err -b), services (systemctl --failed), and disk usage. - Run a final data sync (files plus a fresh database dump), then switch DNS.
Quick reference
| Approach | When |
|---|---|
| Rebuild + copy data | Clean, documented, recommended |
| Full rsync clone | Undocumented legacy server, same OS version |
| After cloning | New hostname, machine-id, SSH host keys, certs |
| Databases | Dump/restore or replication |
Related: Linux disaster recovery plan and VPS scaling.