2021-01-04
I've been on the search for the "perfect" backup solution for a long time -- a search that never ends, because the target is so elusive. Basically the perfect backup is local + offsite, encrypted, incremental (but also full!), withstands bit rot, is not with a commercial cloud vendor, and for some reason that I can't really articulate it isn't Borg Backup either (actually it probably is; Borg Backup seems f***ing awesome, but for some reason I just can't get excited about it).
Borg Deduplicating Archiver With Compression and Encryption
For now I don't even have an offsite backup (shame on me), but I like the simplicity of my local backup. It's really just a small trick with rsync+cp that I picked up at a previous workplace.
It's executed once a week by cron (because I keep mixing cron and systemd.timers for no good reason):
$ cat /etc/cron.d/weekly-backup
# Take an incremental backup of users home directories every Sunday at 5am
0 5 * * 0 root incremental-backup
And the script itself is very short and sweet (for reference /mnt/usb1/users is mounted as /home and /mnt/usb2 is my backup disk):
$ cat /bin/incremental-backup
#!/bin/bash
SOURCE=/mnt/usb1/users
DESTDIR=/mnt/usb2
DEST="${DESTDIR}/latest"
mkdir -p "${DEST}"
rsync --archive --delete --verbose "${SOURCE}" "${DEST}" > "${DEST}/backuplog"
cp -prl "${DEST}" "${DESTDIR}/$(date --iso-8601=minutes)"
The last two commands do the trick. The first rsyncs to a dir called "latest" (which doesn't need to be created which mkdir every time... there is room for improvement even here), keeping ownership and deleting files in the destination directory which have been deleted in the source. This is incremental, and only pushes changes since last backup.
The second command copies the directory "latest" to another directory named as a timestamp. Note the flags:
For each backup I get a directory tree that is a full backup of /home, but it only takes as much room as the changes since last time.
Check it out:
root : usb2 $ du -csh * | sort -k 2
66G 2020-08-16T05:00+02:00
15M 2020-08-23T05:00+02:00
16M 2020-08-30T05:00+02:00
78M 2020-09-06T05:00+02:00
17M 2020-09-13T05:00+02:00
2.9G 2020-09-20T05:04+02:00
304M 2020-09-27T05:00+02:00
260M 2020-10-04T05:00+02:00
1.2G 2020-10-11T05:02+02:00
1.2G 2020-10-18T05:02+02:00
794M 2020-10-25T05:02+01:00
27M 2020-11-01T05:00+01:00
24M 2020-11-08T05:00+01:00
24M 2020-11-15T05:00+01:00
24M 2020-11-22T05:00+01:00
56M 2020-11-29T05:00+01:00
27M 2020-12-06T05:00+01:00
90M 2020-12-13T05:00+01:00
39M 2020-12-20T05:00+01:00
33M 2020-12-27T05:00+01:00
3.5G 2021-01-03T05:05+01:00
24M latest
16K lost+found
76G total
-- CC0 Björn Wärmedal