"...until they get a punch in the mouth." - Mike Tyson
Precis
I now only have one physical server at home, and that's for multimedia umm, acquisition and streaming (not public-facing) and uptime monitor for my off-site server running this Ghost instance, my Nightscout service and Nextcloud instance.
I back the whole box up every night to a Wasabi S3 bucket using the beautifully simple restic using smart retention policy. The output is written to a log file that gets emailed to me for comfort. It's a linux box so I use CRON to schedule the backup. Every month there's a restic check
job to make use everything's ticking along okay.
#!/bin/bash
unset HISTFILE
export AWS_DEFAULT_REGION="[REDACTED]"
export RESTIC_REPOSITORY="[REDACTED]"
export AWS_ACCESS_KEY_ID="[REDACTED]"
export AWS_SECRET_ACCESS_KEY="[REDACTED]"
export RESTIC_PASSWORD="[REDACTED]"
restic -r $RESTIC_REPOSITORY backup --exclude-file=/root/scripts/restic-excludes.txt / --verbose
restic forget --keep-daily 7 --keep-weekly 5 --keep-monthly 12
restic -r $RESTIC_REPOSITORY snapshots
/bin/bash /root/scripts/make-restic-email.sh
exit
/root/scripts/restic-backup.sh
/dev/*
/home/*/.bash_history
/home/*/.cache/chromium
/home/*/.local/share/Trash
/home/*/Documents/Exclude/*
/lib/modules/*/volatile/.mounted
/media/*
/proc/*
/run/*
/tmp/*
/sys/*
/var/cache/apt/archives/*
/var/lock/*
/var/run/*
/var/tmp/*
/var/lib/lxcfs/*
/root/scripts/restic-excludes.txt
#!/bin/bash
email_body="/root/scripts/restic-email.txt"
restic_log="/var/log/restic-backup.log"
echo "To: admin@[REDACTED]" > $email_body
echo "From: root@[REDACTED]" >> $email_body
echo "Subject: [REDACTED] restic backup report" >> $email_body
cat $restic_log >> $email_body
/usr/sbin/sendmail -t < $email_body
/root/scripts/make-restic-email.sh
I should point out that I have msmtp doing the email shenanigans for me. I heartily recommend it, life's too short!
Local backups to remote
I took a decision recently - after another hard drive died in my NAS - to move all my photography and data files over to my iCloud hierarchy (since it's pretty cheap and I'm paying for it anyway).
Fully aware that a sync service is not a backup, I created a couple of LaunchAgents to rsync my ~/Documents/Photography
and ~/Documents/Data
folders to both my Dropbox space and Nextcloud on a regular schedule. I'll only ever edit photos from the iCloud folder, and the rsync operations are only outgoing, so I'm confident that any changes made on the remote storage spaces will not be reflected back to me.
Why fanny about with LaunchAgent when I could run a backup script from CRON? Because I couldn't circumvent the macOS security that prevents CRON jobs from accessing iCloud folders(!) is why. Yes, I did try adding CRON to the list of apps that have full disk access, but gave up in the end and learned how to do it this way instead.
The scripts write the timestamped output to logfiles and I have logrotate keeping them tidy for me.
~/Documents/Photography backup [https://gitlab.com/-/snippets/4867372]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>rsync Documents/Photography to Dropbox /Photography</string>
<key>ProgramArguments</key>
<array>
<string>rsync</string>
<string>-avx</string>
<string>--out-format=%t %f %b</string>
<string>/Users/steve/Documents/Photography/</string>
<string>/Users/steve/Library/CloudStorage/Dropbox/Photography/</string>
</array>
<key>StandardOutPath</key>
<string>/Users/steve/logs/dropbox-backup-photography.log</string>
<key>StandardErrorPath</key>
<string>/Users/steve/logs/dropbox-backup-photography-error.log</string>
<key>StartInterval</key>
<integer>3600</integer>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
Backup /Documents/Photography to Dropbox
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>rsync Documents/Photography to Nextcloud /Photography</string>
<key>ProgramArguments</key>
<array>
<string>rsync</string>
<string>-avx</string>
<string>--out-format=%t %f %b</string>
<string>/Users/steve/Documents/Photography/</string>
<string>/Users/steve/Nextcloud/Photography/</string>
</array>
<key>StandardOutPath</key>
<string>/Users/steve/logs/nextcloud-backup-photography.log</string>
<key>StandardErrorPath</key>
<string>/Users/steve/logs/nextcloud-backup-photography-error.log</string>
<key>StartInterval</key>
<integer>3600</integer>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
Backup /Documents/Photography to Nextcloud
~/Documents/Data backup [https://gitlab.com/-/snippets/4867375]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>rsync Documents/Data to Dropbox /Data</string>
<key>ProgramArguments</key>
<array>
<string>rsync</string>
<string>-avx</string>
<string>--out-format=%t %f %b</string>
<string>/Users/steve/Documents/Data/</string>
<string>/Users/steve/Library/CloudStorage/Dropbox/Data/</string>
</array>
<key>StandardOutPath</key>
<string>/Users/steve/logs/dropbox-backup-data.log</string>
<key>StandardErrorPath</key>
<string>/Users/steve/logs/dropbox-backup-data-error.log</string>
<key>StartInterval</key>
<integer>3600</integer>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
Backup /Documents/Data to Dropbox
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>rsync Documents/Data to Nextcloud /Data</string>
<key>ProgramArguments</key>
<array>
<string>rsync</string>
<string>-avx</string>
<string>--out-format=%t %f %b</string>
<string>/Users/steve/Documents/Data/</string>
<string>/Users/steve/Nextcloud/Data/</string>
</array>
<key>StandardOutPath</key>
<string>/Users/steve/logs/nextcloud-backup-data.log</string>
<key>StandardErrorPath</key>
<string>/Users/steve/logs/nextcloud-backup-data-error.log</string>
<key>StartInterval</key>
<integer>3600</integer>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
Backup /Documents/Data to Nextcloud
For belt-and-braces I also use the desktop client for Filen to 'local backup' the Photography and Data folders.
That's all I wanted to say. Hope it helps someone else decide on a backup strategy without headaches. Want to make a comment or discuss this post? Feel free to write below. Not a subscriber yet? It's free! Sign up here.
You can also find me on Mastodon if you want to start a discussion about it there.