Restore a VPS backup
A backup only protects you if the restore works. When you actually need one, you are usually under pressure: a service is down, an update broke a configuration. This procedure starts from a local archive or a dashboard backup and brings the service back step by step, without destroying anything that might still be useful.
Check the archive before touching the server
First confirm what you are about to restore. A truncated archive or one from another date only adds confusion.
sudo ls -lh /root/backup-2026-11-01.tar.gz
sudo sha256sum /root/backup-2026-11-01.tar.gz
sudo tar -tzf /root/backup-2026-11-01.tar.gz | head -n 20Compare the checksum with the one recorded when the backup was taken. Read through the path list: you should recognise /var/www, /etc/nginx or the relevant application. Then check free space with df -h /: you need room for the archive and for the extracted files.
Preserve the current state before replacing it. Renaming a directory takes seconds and prevents a permanent loss:
sudo mv /var/www/my-site /var/www/my-site.before-restoreRestore files
Stop the service writing to those files first. For a static site Nginx can keep running; for an application, stop it.
sudo systemctl stop my-app
sudo tar -xzpf /root/backup-2026-11-01.tar.gz -C /The -p flag restores permissions and owners when the extraction runs as root. If the archive was created with relative paths, extract it under the right parent. For a single directory, rsync is more selective:
sudo rsync -aHAX --numeric-ids /root/restore/var/www/my-site/ /var/www/my-site/The trailing slash on the source means "the contents of", not the directory itself.
Restore a database
Recreate the database if it no longer exists, then import the dump. A dump taken with --single-transaction is consistent without blocking writes at backup time.
sudo mysql -e "CREATE DATABASE IF NOT EXISTS app CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
gunzip < /root/app-2026-11-01.sql.gz | sudo mysql appOn a large database, import into a temporary database first and compare row counts of the main tables before replacing production.
Verify the service
Restart and check three layers: the process, the network, the application.
sudo systemctl start my-app
sudo systemctl status my-app --no-pager
sudo journalctl -u my-app -n 50 --no-pager
curl -sS -o /dev/null -w '%{http_code}\n' https://your-domain.tld/Then open the application and perform a real write: log in, submit a form, upload a file. Check web file permissions (644 for files, 755 for directories) and the owner expected by the web server.
Good practice
- Restore with the same major version of the software and database engine as the backup.
- Test a full restore into a staging directory at least once a quarter.
- Encrypt archives that contain secrets, then copy them off the VPS: an archive stored only on the machine it protects does not survive a reinstall.
- Record the date, contents and location of each backup in a tracked file, not in your memory.
Advertisement
Was this article helpful?
Read next
- Back up a VPS properlyDecide what to back up on a VPS, produce verified archives and apply the 3-2-1 rule.
- Create a restore point before an updateWhat to save before a version upgrade, and how to roll back if the service does not come back.
- Set up secure SFTP accessProvide SFTP access restricted to one folder with chroot, without a shell or root rights.