GUIDE: Setting up automatic daily backups

I recently had an annoying experience where my PiFi accidentally reset to factory defaults, clearing out all my customizations (only to then realize that I didn’t have an updated backup).

So I decided to share a step-by-step guide for setting up an automatic daily backup for your PiFi. I decided to store my backups on my mounted cloud drive, but you can modify the guide below to backup anywhere, for example on a small USB thumb drive you keep plugged it for this purpose. Additionally, the script below will automatically ensure that only the 30 most recent backups are retained by deleting older files, to prevent clutter.

Backup Script Overview:
The script performs the following tasks:

  • Ensures the backup destination exists.
  • Reads the OpenWrt version from /etc/openwrt_version (to include that in the filename, to prevent restoring from incompatible versions if there’s a version upgrade)
  • Creates a backup file named with the hostname, current date, and OpenWrt version.
  • Runs the backup.
  • Checks the number of backup files and deletes the oldest ones if more than 30 are present.

The Backup Script Code:

#!/bin/sh
# Set the backup destination folder
BACKUP_DIR="/mnt/htpc/Backups/PiFi"
mkdir -p "$BACKUP_DIR"

# Retrieve the most recent previous backup file, if any
PREV_BACKUP=$(ls -1tr "${BACKUP_DIR}"/backup-* 2>/dev/null | tail -n 1)
if [ -n "$PREV_BACKUP" ]; then
    echo "Previous backup file: $PREV_BACKUP"
else
    echo "No previous backup file found."
fi

# Retrieve the OpenWrt version from /etc/openwrt_version if it exists
if [ -f /etc/openwrt_version ]; then
    OPENWRT_VERSION=$(cat /etc/openwrt_version)
else
    OPENWRT_VERSION="unknown"
fi

# Construct the backup file name: includes hostname, current date, time (hours and minutes), and OpenWrt version
BACKUP_FILE="${BACKUP_DIR}/backup-${HOSTNAME}-$(date +%F-%H%M)-${OPENWRT_VERSION}.tar.gz"

# Create the backup using sysupgrade in backup mode
sysupgrade -b "$BACKUP_FILE"

# If a previous backup exists and its name is different from the new backup file, compare MD5 hashes
if [ -n "$PREV_BACKUP" ] && [ "$PREV_BACKUP" != "$BACKUP_FILE" ]; then
    NEW_HASH=$(md5sum "$BACKUP_FILE" | awk '{print $1}')
    PREV_HASH=$(md5sum "$PREV_BACKUP" | awk '{print $1}')
    
    if [ "$NEW_HASH" = "$PREV_HASH" ]; then
        echo "New backup ($BACKUP_FILE) is identical to previous backup ($PREV_BACKUP). Removing duplicate."
        rm -f "$BACKUP_FILE"
    fi
fi

# Keep only the most recent 30 backup files (files starting with "backup-")
NUM_FILES=$(ls -1 "${BACKUP_DIR}"/backup-* 2>/dev/null | wc -l)
if [ "$NUM_FILES" -gt 30 ]; then
    NUM_TO_DELETE=$(expr "$NUM_FILES" - 30)
    ls -1tr "${BACKUP_DIR}"/backup-* 2>/dev/null | head -n "$NUM_TO_DELETE" | while read file; do
        rm -f "$file"
    done
fi

Explanation of the Script:

  • Backup Directory Creation: The script sets the backup folder to /mnt/htpc/Backups/PiFi and ensures it exists by creating it if needed. You can replace that folder with whatever you want.
  • Retrieving OpenWrt Version: It reads the version from /etc/openwrt_version and defaults to “unknown” if the file isn’t found.
  • Constructing the Filename: The backup file is named using the device’s hostname, the current date (in YYYY-MM-DD format), and the OpenWrt version.
  • Creating the Backup: The sysupgrade -b command is used to generate the backup.
  • Managing Backup Files: The script counts how many backup files exist. If there are more than 30, it deletes the oldest ones to maintain only the latest 30 backups. If a daily backup happens and it is identical to the previous day backup then the current backup will not be saved (to prevent redundant duplicate backups).

Setting Up the Script:

  1. Create the Script File:
    Save the above script as /root/backup_openwrt.sh using your favorite text editor (e.g., vi or nano).
  2. Make the Script Executable:
    Run the following command to give it executable permissions:
chmod +x /root/backup_openwrt.sh
  1. Test the Script:
    Execute the script manually:
/root/backup_openwrt.sh

Verify that a backup file with a name like backup-[hostname]-YYYY-MM-DD-[version].tar.gz appears in your backup folder.

Scheduling the Backup with Cron:

To run the backup daily, add a cron entry:

  1. In LuCI, go to System → Scheduled Tasks (or edit /etc/crontabs/root) with vi /etc/crontabs/root)
  2. Add the following line to schedule the script to run daily at 22:00 (10 PM):
0 22 * * * /root/backup_openwrt.sh
  1. Save the file and restart the cron service:
/etc/init.d/cron restart

I hope this is useful for others as well, happy backing up!

Update 1: Updated the script so consecutive duplicate backups will not be stored. So if nothing changed on a given day, no need to keep duplicate backups. It’ll only keep the backup if it is different than the previous one.

2 Likes

Looks a great guide!