Backup a Headless Server with rsync

Use rsync over SSH to copy files from a headless Linux server to a backup machine. This gives you fast incremental backups, compression, and an easy way to verify changes.
Safety note
Test commands on a small folder first. Be careful with --delete (it removes files from the destination that no longer exist on the source).

  • SSH access to the headless server: user@server
  • rsync installed on both machines (server and backup host)
  • Enough disk space on the backup host
Install rsync
Debian/Ubuntu
sudo apt update
sudo apt install -y rsync
RHEL/Fedora
sudo dnf install -y rsync

Generate a key on the backup host and copy it to the server so backups can run without typing a password:
ssh-keygen -t ed25519 -a 64
ssh-copy-id user@server
Optional: add ~/.ssh/config entries to simplify the rsync command.

Run this on the backup host. It simulates what will change:
rsync -avz --progress --dry-run \
  -e "ssh -p 22" \
  user@server:/etc/  /backups/server/etc/
Common flags
  • -a archive mode (preserves perms, times, symlinks)
  • -v verbose
  • -z compression
  • --dry-run don’t change anything

After the dry run looks right, remove --dry-run and (optionally) add --delete:
rsync -avz --delete --progress \
  -e "ssh -p 22" \
  user@server:/home/  /backups/server/home/
Warning
--delete deletes on the destination. Use only if the destination should be an exact mirror of the source.

Create an exclude file on the backup host:
cat > excludes.txt <<'EOF'
*.tmp
*.cache
.cache/
node_modules/
EOF
Then run rsync with excludes:
rsync -avz --delete --progress \
  --exclude-from="excludes.txt" \
  -e "ssh -p 22" \
  user@server:/var/www/  /backups/server/var_www/

Put your rsync in a script (example /usr/local/bin/backup_server.sh on the backup host):
#!/usr/bin/env bash
set -euo pipefail

rsync -avz --delete \
  --exclude-from="/backups/excludes.txt" \
  -e "ssh -p 22" \
  user@server:/home/  /backups/server/home/
Add a cron job:
crontab -e

# Every day at 2:15 AM
15 2 * * * /usr/local/bin/backup_server.sh >> /var/log/backup_server.log 2>&1

Verify by listing and spot-checking files on the backup host:
du -sh /backups/server/home/
ls -la /backups/server/etc/ | head
Restore is just rsync in the opposite direction (be careful!):
rsync -avz --progress \
  /backups/server/etc/  user@server:/etc/
Quality, Reliability & Service
Thank You For Visiting
Brooks Computing Systems - Jacksonville
Visit https://bcs.archman.us