05 February 2025
Continuing on the Borg and Flint Router theme, the latest task is to backup my Ubuntu laptop to storage attached to the Flint router.
The best way to backup to a remote location is to install Borg remotely, but with larger backup repositories, it can need significant memory, and the router hasn't got much spare.
However, Borg can backup to a remote filesystem mounted using sshfs and it seems to work well for my limited requirements.
The plan is to use an hourly cron task and run a small script to perform the backup. The tricky thing about backups, is you need to know when they fail. On a server, something like Cronitor is a perfect way to alert about failed jobs.
On the desktop, backups will only run when the machine is on and likely being used. Therefore a failed cron job could alert with a notification via notify-send, which will pop up on the desktop.
Create a new public / private key pair without a passphrase and add it to the authorized_keys on the router. The lack of pass phrase is important, as there is no way for cron to enter the password. Then init a new borg repo at that location.
Create a script somewhat like the following:
#!/bin/bash
set -e
log () {
echo " $(date '+%d/%m/%Y %H:%M:%S'): $1"
}
BACKUP_FOLDER=/home/sodonnell
export BORG_REPO=/home/sodonnell/backup/thinkpad-borg
export BORG_PASSPHRASE='SomePassword'
log "mounting remote backup location"
sshfs sodonnell@192.168.8.1:/mnt/backup/thinkpad-borg /home/sodonnell/backup -o uid=1000 -o gid=1000 -o IdentityFile=/home/sodonnell/.ssh/id_ed25519_backups
log "Running borg backup"
/usr/bin/borg create \
--verbose \
--filter AME \
--list \
--stats \
--show-rc \
--compression zstd,5 \
--exclude-caches \
--exclude $BACKUP_FOLDER/Downloads \
--exclude $BACKUP_FOLDER/scratch \
--exclude $BACKUP_FOLDER/.cache \
--exclude $BACKUP_FOLDER/.local/share/JetBrains \
--exclude $BACKUP_FOLDER/.local/share/Trash \
\
::'thinkpad-home-{now}' \
$BACKUP_FOLDER
/usr/bin/borg prune \
--list \
--glob-archives 'thinkpad-home-*' \
--show-rc \
--keep-daily 7 \
--keep-weekly 4 \
--keep-monthly 2
/usr/bin/borg compact
log "backup completed"
fusermount -u /home/sodonnell/backup
log "Backup FS unmounted"
I also created a wrapper script to call this one, and send the notification if it fails, eg: ```
export DBUSSESSIONBUS_ADDRESS="unix:path=/run/user/1000/bus"
/home/sodonnell/source/scripts/backup/backup-home.sh || /usr/bin/notify-send -u critical -a backups "Backups failed. Check log"
``
The
DBUS` environment variable was obtained from my shell environment, and is needed for notify-send to work.
Finally, schedule this wrapper in cron:
$ crontab -l
SHELL=/bin/bash
0 * * * * /home/sodonnell/source/scripts/backup/backup-home-wrapper.sh &>> /home/sodonnell/scratch/backup.log
The default shell is /bin/sh, which doesn't support the &>>
syntax, hence the SHELL=/bin/bash
line in the crontab.