How to Move a Linux Server to New Hardware (Clone the Disk or Rebuild Clean)

Move your server to new hardware: Clone the disk, or rebuild clean. Rebuild is usually better.

The old PC is wheezing, or you've bought a mini PC that uses a tenth of the power. Moving a Linux server is far less painful than moving a Windows one, and if you've followed this series — data in ~/docker, configs in /etc, backups that you've tested — you have a choice: clone the disk exactly, or rebuild clean and restore. Both are described here; the second is usually better.

Quick reference

ApproachBest whenTime
Clone the disk (Clonezilla / dd)same architecture, you want everything identical, can't face reinstalling1 hour
Rebuild and restoremoving between very different hardware, Pi ↔ x86, or the old install has accumulated cruftan afternoon

Either way, finish with the same checklist at the end.

Option A: Clone the disk

  1. Download Clonezilla Live, write it to a USB stick (Rufus), and boot the old server from it with the new drive attached (USB adapter, or a second bay).
  2. Choose device-device → disk_to_local_disk, source = old disk, target = new disk. Confirm twice. If the new disk is bigger, choose the -k1 option to grow the partition proportionally, or grow it afterwards (tutorial 64).
  3. Move the new drive into the new machine and boot.

For a drive on another machine over the network, dd through SSH works too: sudo dd if=/dev/sda bs=4M status=progress | ssh john@newserver "sudo dd of=/dev/sda bs=4M" — only with the old system booted from a live USB, never while it's running.

Then fix what hardware changed:

Option B: Rebuild clean and restore

Cleaner, and the better choice most of the time.

  1. Install Ubuntu Server on the new machine (tutorial 1), same username and UID (id on the old server; the installer's first user is 1000, which is usually what you had).
  2. Basics: SSH keys, sudo user, updates, UFW, Fail2ban, hostname and time zone, static IP (tutorials 3 to 9). Half an hour with this series open.
  3. Install Docker (tutorial 24) and anything host-installed — Nginx, MariaDB, Samba, Tailscale. ~/packages-before.txt from the old server (dpkg --get-selections) tells you what you had.
  4. Restore data: from the backup drive or restic (restic restore latest --target /), or rsync straight from the old machine while it's still on: ` rsync -aAX john@oldserver:/home/john/ /home/john/ sudo rsync -aAX john@oldserver:/etc/ /tmp/old-etc/ # review, then copy what you need sudo rsync -aAX john@oldserver:/srv/ /srv/ sudo rsync -aAX john@oldserver:/var/www/ /var/www/ ` Don't blindly copy /etc over the new one — pick the files you edited (nginx/sites-available, samba/smb.conf, fail2ban/jail.local, ssh/sshd_config, msmtprc, exports, fstab lines for data drives).
  5. Databases: restore dumps (mysql < dump.sql), not files.
  6. cd ~/docker/* and docker compose up -d in each folder. Images download; data is already there.

The checklist (both options)

Keep the old server for a week

Switch it off but don't wipe it. Something always surfaces — a cron job you'd forgotten, a Samba share someone uses once a month. After a week with no surprises, wipe it or repurpose it as the backup target.

Troubleshooting

Cloned disk won't boot on UEFI/BIOS mismatch. The old machine was BIOS and the new one is UEFI (or vice versa). Rebuilding is faster than converting.

Permission errors on restored files. UIDs differ. ls -ln and sudo chown -R 1000:1000 as appropriate.

Docker apps start but data is empty. Compose files restored to a different path than the data. Match the folder structure exactly.

Everything works but it's slow. The new NVMe is fine; the old fstab had noatime/mount options you didn't carry over, or the BIOS has power saving at maximum.

Wrapping up

Clone if you must, rebuild if you can. With data in ~/docker, configs you know you edited, tested backups and this checklist, a server migration is an afternoon — and the rebuild leaves you with a clean machine that you understand completely.

Call us