Posted on
Artificial Intelligence

Intelligent Backup Automation

Author
  • User
    linuxbash
    Posts by this author
    Posts by this author

Intelligent Backup Automation: Smarter Bash Workflows You’ll Actually Trust

If you’ve ever discovered a broken backup right when you needed it, you know the sting. Backups that aren’t automated, verified, and recoverable are just wishful thinking. The good news: Linux gives you the building blocks to build intelligent, boringly-reliable backups with simple Bash, a few well-chosen tools, and automation that fits how you work.

In this guide, you’ll learn why smarter backups matter and how to implement them with real-world, copy-pasteable scripts and timers. You’ll get fast local snapshots, encrypted offsite backups, event-driven micro-backups, and health checks—without heavy, opaque appliances.


Why “Intelligent” Backups?

  • Modern risk is multi-dimensional: ransomware, accidental deletions, disk failure, sync-tool mishaps, stolen laptops.

  • Scale and complexity: data sprawls across laptops, VMs, and containers. Nightly cron jobs aren’t enough to keep RPO/RTO low.

  • Silent failure is common: stale cron entries and misconfigured excludes cause “backups” that don’t restore.

  • Linux is a composable powerhouse: combine rsync, restic, inotify, and systemd for a solution that’s fast, deduplicated, encrypted, verifiable, and observable.

Adopt the 3-2-1 rule:

  • 3 copies of your data

  • 2 different media (local snapshots + offsite)

  • 1 offsite (preferably immutable and encrypted)


Tools you’ll use

  • rsync: efficient local snapshots with hard links (near-instant “versioning”)

  • restic: encrypted, deduplicated, verifiable offsite backups

  • inotify-tools: event-driven triggers for “micro” backups as you work

  • systemd timers: resilient, persistent scheduling (better than fragile cron in most cases)

  • Optional: rclone for providers restic doesn’t natively support

Install the tools

APT (Debian/Ubuntu):

sudo apt update
sudo apt install -y rsync restic inotify-tools rclone
# Optional (if you prefer cron):
sudo apt install -y cron

DNF (Fedora/RHEL/CentOS Stream):

sudo dnf install -y rsync restic inotify-tools rclone
# Optional (if you prefer cron):
sudo dnf install -y cronie

Zypper (openSUSE):

sudo zypper refresh
sudo zypper install -y rsync restic inotify-tools rclone
# Optional (if you prefer cron):
sudo zypper install -y cronie

Actionable Plan (5 Steps)

1) Define scope and rules (don’t skip this)

Create explicit include/exclude lists so your backups are deterministic and reviewable.

# /etc/backup.includes
/home
/etc
/var/www

# /etc/backup.excludes
# Caches and junk:
**/.cache
/var/cache
/tmp
**/node_modules
**/.venv
# Large/ephemeral:
**/*.iso
**/*.qcow2
  • Review quarterly; commit to Git for auditability.

  • Tag hosts consistently (hostname-based paths) so restores are predictable.


2) Fast local snapshots with rsync + hard links

rsync can create “versioned” snapshots by hard-linking unchanged files from the previous snapshot. This yields cheap incremental versions you can browse with ls.

Script:

# /usr/local/sbin/backup-local-snapshots.sh
#!/usr/bin/env bash
set -euo pipefail

SRCS=(
  "/home"
  "/etc"
  "/var/www"
)
EXCLUDES="/etc/backup.excludes"
BASE="/backups/$(hostname)/local"
TS="$(date +%F_%H%M%S)"
TARGET="${BASE}/${TS}"
PREV="${BASE}/latest"

mkdir -p "$TARGET"

# Build rsync args
RSYNC_ARGS=(
  -aAXH --delete --numeric-ids
  --info=stats2
  --exclude-from="$EXCLUDES"
)

if [[ -L "$PREV" || -d "$PREV" ]]; then
  RSYNC_ARGS+=(--link-dest="$PREV")
fi

rsync "${RSYNC_ARGS[@]}" "${SRCS[@]}" "$TARGET/"

ln -sfn "$TARGET" "$PREV"

# Prune: keep latest 30 snapshots
cd "$BASE"
ls -1d 20* 2>/dev/null | sort -r | tail -n +31 | while read -r old; do
  rm -rf -- "$old"
done

Systemd service and timer:

# /etc/systemd/system/rsync-snapshots.service
[Unit]
Description=Nightly rsync snapshot backups

[Service]
Type=oneshot
Nice=10
IOSchedulingClass=best-effort
IOSchedulingPriority=7
ExecStart=/usr/local/sbin/backup-local-snapshots.sh

# /etc/systemd/system/rsync-snapshots.timer
[Unit]
Description=Run rsync snapshot backups nightly

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

[Install]
WantedBy=timers.target

Enable:

sudo systemctl daemon-reload
sudo systemctl enable --now rsync-snapshots.timer

Why this helps:

  • Local restores are instant.

  • Snapshots are browseable and don’t need a special tool.

  • Hard links make unchanged data nearly free in space and time.


3) Encrypted, deduplicated offsite backups with restic (S3/B2)

Use restic to push encrypted, space-efficient backups to object storage (S3, Backblaze B2, etc.). Keep secrets out of scripts.

Example: S3 (adjust region/bucket):

# /etc/restic/env
export RESTIC_REPOSITORY="s3:https://s3.eu-central-1.amazonaws.com/my-backups/host-$(hostname)"
export RESTIC_PASSWORD_FILE="/etc/restic/pass"
export AWS_ACCESS_KEY_ID="AKIA..."
export AWS_SECRET_ACCESS_KEY="..."

# Recommended perms:
# sudo mkdir -p /etc/restic && sudo chown root:root /etc/restic
# echo "long-unique-password" | sudo tee /etc/restic/pass >/dev/null
# sudo chmod 600 /etc/restic/pass /etc/restic/env

Backup script:

# /usr/local/sbin/backup-offsite-restic.sh
#!/usr/bin/env bash
set -euo pipefail

source /etc/restic/env

INCLUDES="/etc/backup.includes"
EXCLUDES="/etc/backup.excludes"

# Initialize repo if needed
if ! restic snapshots >/dev/null 2>&1; then
  restic init
fi

# Backup with tags for traceability
restic backup \
  --files-from "$INCLUDES" \
  --exclude-file "$EXCLUDES" \
  --tag "host=$(hostname)" \
  --tag "profile=offsite"

# Retention policy: tune as needed
restic forget --prune \
  --keep-daily 7 \
  --keep-weekly 4 \
  --keep-monthly 12

Systemd timer (e.g., every 6 hours for better RPO):

# /etc/systemd/system/restic-offsite.service
[Unit]
Description=Offsite encrypted backup with restic

[Service]
Type=oneshot
EnvironmentFile=/etc/restic/env
ExecStart=/usr/local/sbin/backup-offsite-restic.sh

# /etc/systemd/system/restic-offsite.timer
[Unit]
Description=Run offsite restic backups every 6 hours

[Timer]
OnCalendar=*-*-* *:00/6:00
Persistent=true

[Install]
WantedBy=timers.target

Enable:

sudo systemctl daemon-reload
sudo systemctl enable --now restic-offsite.timer

Optional: using rclone remotes (for non-S3 providers). After configuring a remote:

# Example: create a Backblaze B2 remote via rclone
rclone config create myb2 b2 account yourAccountID key yourAppKey
# Then point restic to it:
export RESTIC_REPOSITORY="rclone:myb2:my-bucket/host-$(hostname)"

4) Event-driven “micro” backups while you work (inotify)

Reduce data loss between scheduled runs by watching for file changes and batching small incremental backups.

Watcher script:

# /usr/local/sbin/backup-watch.sh
#!/usr/bin/env bash
set -euo pipefail

WATCH_PATHS=(
  "/home/$USER/Documents"
  "/home/$USER/Projects"
)
QUEUE="/var/lib/backup/changed.list"
mkdir -p "$(dirname "$QUEUE")"
touch "$QUEUE"

# Start watcher in background
inotifywait -mrq -e close_write,move,create \
  --format '%w%f' "${WATCH_PATHS[@]}" | while read -r f; do
    # Filter out temp files
    [[ "$f" =~ (\.swp|~|\.tmp)$ ]] && continue
    echo "$f" >> "$QUEUE"
  done &
echo $! > /var/run/backup-watch.pid

echo "Watching started (PID $(cat /var/run/backup-watch.pid))"

Batch-and-backup unit (runs every 10 minutes, deduped by restic):

# /usr/local/sbin/backup-watch-batch.sh
#!/usr/bin/env bash
set -euo pipefail
source /etc/restic/env
QUEUE="/var/lib/backup/changed.list"
TMP="$(mktemp)"

# De-dupe list and keep only existing files
if [[ -s "$QUEUE" ]]; then
  sort -u "$QUEUE" | while read -r f; do
    [[ -f "$f" ]] && echo "$f"
  done > "$TMP"
  : > "$QUEUE"  # clear queue

  if [[ -s "$TMP" ]]; then
    restic backup --files-from "$TMP" --tag "micro" --tag "host=$(hostname)"
  fi
fi
rm -f "$TMP"

Systemd units:

# /etc/systemd/system/backup-watch.service
[Unit]
Description=File change watcher for micro-backups
After=network-online.target

[Service]
Type=simple
ExecStart=/usr/local/sbin/backup-watch.sh
Restart=always

# /etc/systemd/system/backup-watch-batch.service
[Unit]
Description=Batch changed files into a restic micro-backup

[Service]
Type=oneshot
EnvironmentFile=/etc/restic/env
ExecStart=/usr/local/sbin/backup-watch-batch.sh

# /etc/systemd/system/backup-watch-batch.timer
[Unit]
Description=Run micro-backup batch every 10 minutes

[Timer]
OnBootSec=5m
OnUnitActiveSec=10m
Persistent=true

[Install]
WantedBy=timers.target

Enable:

sudo systemctl daemon-reload
sudo systemctl enable --now backup-watch.service backup-watch-batch.timer

5) Verification, restore drills, and monitoring

Backups you don’t test are backups you don’t have.

  • Verify repository integrity (schedule weekly):
restic check --with-cache
# Or read a sample of data blocks:
restic check --read-data-subset=10%
  • Practice restores (file-level):
# List snapshots
restic snapshots

# Restore last version of a path to a safe temp location
restic restore latest --target /tmp/restore-test --include "/home/$USER/Documents/important.docx"
  • Simple monitoring/alerts (Healthchecks.io example):
# Wrap your backup scripts:
curl -fsS -m 10 https://hc-ping.com/YOUR-UUID/start
/usr/local/sbin/backup-offsite-restic.sh && \
  curl -fsS -m 10 https://hc-ping.com/YOUR-UUID
  • Keep logs:
journalctl -u rsync-snapshots.service --since "yesterday"
journalctl -u restic-offsite.service --since "yesterday"

Real-world patterns that work

  • Laptops: hourly local rsync snapshots + 6-hourly restic offsite + event-driven micro-backups on Documents/Projects.

  • Servers: nightly rsync snapshots for fast rollback + 6-hourly restic to S3 with stricter retention and weekly restic check.

  • Small teams: one bucket per host with tags; a separate “cold” account for long-term archives; rotate credentials quarterly.


Conclusion and Next Steps

Backups should be boring, fast, and verifiable. With rsync for local time-machine-like snapshots, restic for encrypted offsite deduplication, inotify for smart micro-backups, and systemd timers for dependable scheduling, you’ll have a setup that’s both intelligent and transparent.

Your next steps: 1) Install the tools (see commands above). 2) Create /etc/backup.includes and /etc/backup.excludes. 3) Enable the rsync snapshot and restic timers. 4) Run a restore drill today. Prove it works.

Have questions or want a follow-up on immutability (object locks), key management, or multi-host orchestration? Tell me what environment you’re backing up and I’ll share a tailored blueprint.