From 7044c9b52f9c6b7aa2a006f09198fe98addcfc9d Mon Sep 17 00:00:00 2001 From: Timo Wilken Date: Sat, 18 Feb 2023 00:27:17 +0100 Subject: Extract common service sets into separate modules Common service sets (NextCloud, Matrix, WireGuard) should be in their own modules to make things neater, instead of being interleaved with operating system declarations. --- tw/services/files/nextcloud-backup | 68 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100755 tw/services/files/nextcloud-backup (limited to 'tw/services/files/nextcloud-backup') diff --git a/tw/services/files/nextcloud-backup b/tw/services/files/nextcloud-backup new file mode 100755 index 00000000..4c533758 --- /dev/null +++ b/tw/services/files/nextcloud-backup @@ -0,0 +1,68 @@ +#!/bin/sh -e +# Nextcloud backup script, to run nightly. +# Documentation on backups: +# https://docs.nextcloud.com/server/latest/admin_manual/maintenance/backup.html +# https://docs.nextcloud.com/server/latest/admin_manual/maintenance/restore.html +# https://git.mdns.eu/nextcloud/passwords/-/wikis/Administrators/Backups + +. /etc/default/nextcloud-backup +: "${DATABASE_PASSWORD:?You must pass the MySQL database password as DATABASE_PASSWORD}" + +php_ini=$1 +backup_dir=/var/backups/nextcloud/$(date -u '+%Y-%m-%d') +nextcloud_dir=/var/www/nextcloud +nextcloud_data_partition=/var/data # mountpoint of the partition containing Nextcloud data dir +nextcloud_data_path=nextcloud # relative to $nextcloud_data_partition +snapshot=$nextcloud_data_partition/tmp-nextcloud-backup + +nc_maintenance () { + # Enable (--on) or disable (--off) Nextcloud's maintenance mode. + sudo -nu httpd php ${php_ini:+-c "$php_ini"} "$nextcloud_dir/occ" maintenance:mode "$@" +} + +# If there is a previous backup, compare against it later (so we don't have to +# transfer every file). +last_backup_dir=$(ls -1d "$(dirname "$backup_dir")"/????-??-?? | LC_ALL=C sort | tail -1) +[ -d "$last_backup_dir" ] || unset last_backup_dir + +# Don't overwrite existing backups. mkdir will fail if $backup_dir exists. +mkdir -m 750 "$backup_dir" + +# Always turn off maintenance mode and clean up the temporary snapshot on exit, +# whether or not the backup succeeded. +cleanup () { + nc_maintenance --off || : + if [ -d "$snapshot" ]; then + btrfs subvolume delete -c "$snapshot" || : + fi +} +trap cleanup EXIT HUP INT TERM # can't trap KILL + +# Turn Nextcloud off temporarily so the data doesn't change during the backup. +nc_maintenance --on + +# Backup the database. This can only be done offline. +mysqldump --single-transaction --default-character-set=utf8mb4 \ + -u nextcloud -p"$DATABASE_PASSWORD" nextcloud > "$backup_dir/nextcloud.sql" + +# These shouldn't be copied while Nextcloud is online. +rsync -AUXHavx ${last_backup_dir+--link-dest="$last_backup_dir"} \ + "$nextcloud_dir/config" "$nextcloud_dir/themes" "$backup_dir" + +# Make sure everything is synced to disk so it's in our snapshot. +btrfs filesystem sync "$nextcloud_data_partition/$nextcloud_data_path" +btrfs subvolume snapshot -r "$nextcloud_data_partition" "$snapshot" + +# At this point, the data directory is in the snapshot, so Nextcloud can be +# turned on again. +nc_maintenance --off + +# --link-dest is brittle (it only hardlinks to the old file if no metadata has +# changed). Reflinks would be better, but rsync doesn't seem to support them. +# We don't need files under preview/, as those are thumbnails from the Previews +# "app" and can be regenerated using `php -f occ preview:pre-generate`. +rsync -AUXHavx --exclude='appdata_*/preview' --exclude='appdata_*/passwords/*Cache' \ + ${last_backup_dir+--link-dest="$last_backup_dir/data"} \ + "$snapshot/$nextcloud_data_path/" "$backup_dir/data" +# Make sure everything is written out to the backup disk before we exit. +btrfs filesystem sync "$backup_dir" -- cgit v1.2.3