SSH Backup with Rsync
rsync over SSH is a reliable way to move backups to another server. It supports resumable transfers, preserves metadata, and can be made safe-by-default (no deletion until you trust the pipeline).
Quick Summary
- Prefer
rsyncoverscpfor repeatable offsite copies. - Start without
--delete. - Use a dedicated SSH key and restricted backup user.
- Verify: list remote files and compare checksums.
Prerequisites
- A remote server with enough space.
- SSH access to the remote.
rsyncinstalled on both ends.
check-rsync-installed.sh
rsync --version
ssh -V
Set up SSH key-based access
Generate a dedicated key:
generate-backup-ssh-key.sh
ssh-keygen -t ed25519 -f ~/.ssh/wp-backup -C "wp-backup"
Copy the public key to the remote backup user:
install-ssh-key-on-remote.sh
ssh-copy-id -i ~/.ssh/wp-backup.pub backup@backup-host
Push backups to the remote (safe default)
This copies local backups to the remote without deleting anything.
rsync-push-backups-safe.sh
rsync -az \
-e 'ssh -i ~/.ssh/wp-backup -o StrictHostKeyChecking=accept-new' \
--info=stats2,progress2 \
/backups/ \
backup@backup-host:/srv/wp-backups/site-a/
Exclude unnecessary artifacts
Exclude nested archives and temporary files.
rsync-push-with-excludes.sh
rsync -az \
-e 'ssh -i ~/.ssh/wp-backup -o StrictHostKeyChecking=accept-new' \
--exclude '*.tmp' \
--exclude '*.partial' \
--exclude '*.bak' \
/backups/ \
backup@backup-host:/srv/wp-backups/site-a/
Mirror mode (with deletion)
warning
--delete removes files on the remote that do not exist locally. If your local disk is missing files, --delete can propagate the loss.
Only use mirror mode when you intentionally want the remote to track local state:
rsync-push-mirror-with-delete.sh
rsync -az \
--delete \
-e 'ssh -i ~/.ssh/wp-backup -o StrictHostKeyChecking=accept-new' \
/backups/ \
backup@backup-host:/srv/wp-backups/site-a/
Verification
List remote files:
verify-remote-files-over-ssh.sh
ssh -i ~/.ssh/wp-backup backup@backup-host 'ls -lah /srv/wp-backups/site-a | sed -n "1,80p"'
Checksum verification (example with sha256):
checksum-verify-local-vs-remote.sh
cd /backups
sha256sum wp-files-*.tar.* wp-db-*.sql.* | tail -n 10 > /tmp/local.sha256
scp -i ~/.ssh/wp-backup /tmp/local.sha256 backup@backup-host:/tmp/local.sha256
ssh -i ~/.ssh/wp-backup backup@backup-host 'cd /srv/wp-backups/site-a && sha256sum -c /tmp/local.sha256'
Restore direction (pull from remote)
If the VPS is rebuilt, you can pull backups down:
rsync-pull-backups-from-remote.sh
sudo mkdir -p /backups
sudo rsync -az \
-e 'ssh -i ~/.ssh/wp-backup -o StrictHostKeyChecking=accept-new' \
backup@backup-host:/srv/wp-backups/site-a/ \
/backups/
Next steps
- Retention and pruning:
opt/docker-data/apps/docusaurus/site/docs/server/linux-server/10-backup-disaster-recovery/rotation--retention-policies.mdx. - Permissions for backup storage:
opt/docker-data/apps/docusaurus/site/docs/server/linux-server/10-backup-disaster-recovery/storage-permissions.mdx.