A backup that lives on the same machine as your data isn't a backup — it's a copy waiting to disappear with the disk. If you run anything on a VPS that you'd be unhappy to lose (a database, a game world, a self-hosted app), you want backups that run on a schedule, leave the server, and can actually be restored. Here's a clean, honest setup using restic, which is free, open-source, encrypted by default, and deduplicates so repeated backups stay small.
1. Install restic
On Debian/Ubuntu:
sudo apt update && sudo apt install -y restic
On AlmaLinux/Rocky:
sudo dnf install -y epel-release && sudo dnf install -y restic
2. Pick an off-site destination
The whole point is "not on this server." Good options: an S3-compatible object store, a second VPS in another region, or an SFTP target. restic encrypts everything client-side before it leaves the box, so the destination never sees your plaintext.
export RESTIC_REPOSITORY="sftp:backup@backup-host:/srv/restic/myvps"
export RESTIC_PASSWORD="a-long-random-passphrase-you-store-safely"
restic init
Keep that passphrase somewhere safe and separate. Without it, the repository is unrecoverable — which is exactly what protects you if the backup host is ever compromised.
3. Back up the things that matter
Don't back up the whole root filesystem — you'll just restore the OS. Back up your data:
restic backup /var/lib/mysql /var/www /etc /home --exclude-caches
For databases, dump first so you get a consistent snapshot rather than copying live files:
mysqldump --single-transaction --all-databases > /root/db-$(date +%F).sql
restic backup /root/db-*.sql
4. Automate it with a timer
Drop this into /usr/local/sbin/backup.sh, make it executable, and let cron run it nightly:
#!/bin/bash
set -euo pipefail
export RESTIC_REPOSITORY="sftp:backup@backup-host:/srv/restic/myvps"
export RESTIC_PASSWORD_FILE="/root/.restic-pass"
mysqldump --single-transaction --all-databases > /root/db.sql
restic backup /var/www /etc /root/db.sql --exclude-caches
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
chmod 700 /usr/local/sbin/backup.sh
echo "15 3 * * * root /usr/local/sbin/backup.sh >> /var/log/backup.log 2>&1" | sudo tee /etc/cron.d/restic-backup
The forget --prune line is the part people skip — it keeps a sensible retention window so the repository doesn't grow forever.
5. Test the restore (this is the real step)
An untested backup is a hope, not a plan. Once a month, prove it works:
restic snapshots
restic restore latest --target /tmp/restore-test --include /etc
If the files come back, you have a backup. If they don't, you found out on a Tuesday instead of during a disaster.
A note on where this runs
restic is region-agnostic — it works the same whether your VPS is in the EU or the US, and the encrypted-before-it-leaves design means you stay in control of your data wherever the backup target lives. If you're spinning up a box for this, overnight.host runs KVM VPS with full root and honest specs (SSD, NAT IPv4 disclosed up front), hosted in your region — so you can point your off-site backups at a second region without overthinking it.
Top comments (0)