A backup only counts if it lives somewhere other than the server and you have restored from it at least once. This guide builds a simple, dependable routine.
Note: If your plan includes snapshots, take one in the control panel before risky changes. A snapshot is a quick way back, but it is still tied to your service, so keep regular off-server backups as well.
1. Decide what to back up
- Website and app files, for example
/var/www,/srvand/home. - Configuration in
/etc(Nginx, SSH, cron files). - Database dumps, not the live database files.
- Anything else you could not quickly recreate: TLS keys,
.envfiles, uploads.
2. Dump databases first
Copying /var/lib/mysql while the database runs gives an inconsistent copy. Dump to a file instead:
sudo mkdir -p /var/backups/db
sudo mariadb-dump --single-transaction --all-databases | gzip | sudo tee /var/backups/db/mariadb.sql.gz > /dev/null
sudo -u postgres pg_dumpall | gzip | sudo tee /var/backups/db/postgres.sql.gz > /dev/nullKeep only the line for the database you use.
3. Option A: pull a copy with rsync
Run this on your own computer or a backup server, so the VPS never holds credentials to your backups:
rsync -az --delete alex@203.0.113.25:/var/www/ ~/backups/myvps/www/Warning: --delete removes files from the copy that no longer exist on the server. If files are deleted by mistake or by an attacker, the next run deletes them from your copy too. Use dated folders or restic (option B) for real history.
4. Option B: encrypted, versioned backups with restic
restic stores deduplicated, encrypted snapshots on SFTP, S3-compatible storage and more. Install it:
sudo apt install -y restic # Ubuntu / Debian
sudo dnf install -y epel-release && sudo dnf install -y restic # AlmaLinux / RockyCreate a password file and initialise a repository (here over SFTP to another server you control):
sudo sh -c 'openssl rand -base64 32 > /root/.restic-pass && chmod 600 /root/.restic-pass'
sudo restic -r sftp:backup@backup.example.com:/srv/restic/myvps --password-file /root/.restic-pass initWarning: Store a copy of the restic password somewhere safe off the server, such as your password manager. Without it the backups cannot be decrypted by anyone, including you.
5. Automate it
Create /usr/local/bin/backup.sh:
#!/usr/bin/env bash
set -euo pipefail
export RESTIC_REPOSITORY="sftp:backup@backup.example.com:/srv/restic/myvps"
export RESTIC_PASSWORD_FILE="/root/.restic-pass"
mariadb-dump --single-transaction --all-databases | gzip > /var/backups/db/mariadb.sql.gz
restic backup /etc /var/www /home /var/backups/db
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --pruneMake it executable and schedule it nightly in root's crontab (sudo crontab -e):
sudo chmod 700 /usr/local/bin/backup.sh30 2 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&16. Test a restore
sudo restic -r sftp:backup@backup.example.com:/srv/restic/myvps --password-file /root/.restic-pass snapshots
sudo restic -r sftp:backup@backup.example.com:/srv/restic/myvps --password-file /root/.restic-pass restore latest --target /tmp/restore-testCheck a few files in /tmp/restore-test, then delete it. Repeat this every few months.
Troubleshooting
- SFTP repository asks for a password: restic needs key-based SSH from root to the backup host. Add root's public key there.
- Cron job does nothing: read
/var/log/backup.log. Cron'sPATHis minimal, so use full paths if a command is not found. - Backups use too much space: check the
forgetrules and runrestic stats.
