Hack The Sec - Leading Resource Of Linux Tutorial
rsync Backups on Linux — Complete Guide (Local, Remote SSH & Automation)

rsync Backups on Linux — Complete Guide (Local, Remote SSH & Automation)

rsync backup diagram showing incremental file sync from Linux production server to remote backup server over SSH

Every Linux server needs backups. rsync is the standard tool for incremental file sync — copy only what changed, over local disks or SSH, with resume support and exclude patterns.

This guide covers local backups, remote SSH sync, production backup scripts, automation with cron and systemd timers, and the mistakes that cause data loss.

Time required: 30–45 minutes. Prerequisite: SSH key access to remote backup server (see our SSH keys guide).

Table of contents

  1. Why rsync for Linux backups
  2. rsync flags explained (-a, -v, -z, --delete)
  3. Local backup example
  4. Remote backup over SSH
  5. Exclude patterns and include files
  6. Production backup script
  7. Automate with cron
  8. Automate with systemd timer
  9. Verify backups and restore test
  10. Common mistakes

1. Why rsync

  • Incremental: transfers only changed blocks — fast daily backups
  • Preserves permissions: with -a (archive mode)
  • SSH built-in: encrypted remote sync with -e ssh
  • Resume: interrupted transfers can continue
  • Pre-installed on virtually every Linux distro

2. Essential flags

FlagMeaning
-aArchive — permissions, times, symlinks, recursive
-vVerbose — show files transferred
-zCompress during transfer (good over WAN)
-hHuman-readable sizes in output
--deleteDelete files on destination not in source (mirror)
--dry-runPreview without copying — always test first
--excludeSkip paths (cache, tmp, logs)

3. Local backup

# Backup /var/www to external mount
sudo rsync -avh /var/www/ /mnt/backup/www/

# Trailing slash matters!
# /var/www/  → contents of www go into destination
# /var/www   → www directory itself created inside destination

# Dry run first
sudo rsync -avh --dry-run /var/www/ /mnt/backup/www/

4. Remote backup over SSH

# Push local data to remote backup server
rsync -avz -e ssh /var/www/ backup@192.168.1.50:/backup/www/

# With specific SSH key
rsync -avz -e "ssh -i ~/.ssh/id_ed25519_backup" \
  /etc/ backup@192.168.1.50:/backup/etc/

# Pull from remote to local (restore scenario)
rsync -avz -e ssh backup@192.168.1.50:/backup/www/ /var/www-restored/

5. Exclude patterns

# Command-line excludes
rsync -avz --exclude='*.log' --exclude='cache/' --exclude='tmp/' \
  /var/www/ backup@remote:/backup/www/

# Exclude file (recommended for complex lists)
cat > /etc/rsync-excludes.txt <<'EOF'
*.log
cache/
tmp/
node_modules/
.git/
EOF

rsync -avz --exclude-from=/etc/rsync-excludes.txt \
  /var/www/ backup@remote:/backup/www/

6. Production backup script

#!/bin/bash
# /usr/local/bin/backup-www.sh
set -euo pipefail

SRC="/var/www/"
DEST="backup@192.168.1.50:/backup/www/"
SSH_KEY="/root/.ssh/id_ed25519_backup"
LOG="/var/log/rsync-backup.log"
EXCLUDES="/etc/rsync-excludes.txt"

echo "=== Backup started $(date) ===" >> "$LOG"

rsync -avz --delete \
  --exclude-from="$EXCLUDES" \
  -e "ssh -i $SSH_KEY -o StrictHostKeyChecking=yes" \
  "$SRC" "$DEST" >> "$LOG" 2>&1

echo "=== Backup finished $(date) ===" >> "$LOG"
sudo chmod 700 /usr/local/bin/backup-www.sh
sudo chmod 600 /root/.ssh/id_ed25519_backup

7. Automate with cron

# Run daily at 2:30 AM
sudo crontab -e

30 2 * * * /usr/local/bin/backup-www.sh

# Weekly full etc backup Sundays 3 AM
0 3 * * 0 rsync -avz -e "ssh -i /root/.ssh/id_ed25519_backup" /etc/ backup@remote:/backup/etc/

8. Automate with systemd timer

# /etc/systemd/system/backup-www.service
[Unit]
Description=rsync www backup

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup-www.sh

# /etc/systemd/system/backup-www.timer
[Unit]
Description=Daily www backup

[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true

[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable --now backup-www.timer
systemctl list-timers | grep backup

9. Verify and restore test

# Compare source and destination file counts
find /var/www -type f | wc -l
ssh backup@remote 'find /backup/www -type f | wc -l'

# Monthly restore drill — pull one file back
rsync -avz -e ssh backup@remote:/backup/www/index.html /tmp/restore-test/

# Check backup log for errors
grep -i error /var/log/rsync-backup.log

10. Common mistakes

  • Missing trailing slash: backs up wrong directory structure
  • --delete without testing: can wipe backup if source path is wrong — always dry-run first
  • Backing up running databases with rsync alone: use mysqldump or pg_dump for DB data, rsync for files
  • No restore test: backups you never restore are faith, not strategy
  • Root SSH login for backups: use a dedicated backup user with restricted authorized_keys command= option

Bottom line: rsync -avz -e ssh plus a daily cron or systemd timer is the simplest reliable backup stack for Linux file data. Test with --dry-run, exclude caches, and verify restores monthly.

H

About the author

I am a Linux Administrator and Security Expert. Through this site I share Linux tutorials, hardening guides and security news.

Comments