#!/bin/sh
set -eu

# A backup script to backup Nextcloud as described in
# https://docs.nextcloud.com/server/latest/admin_manual/maintenance/backup.html.
# This runs inside a different Docker container that has access to the Docker
# daemon so it can run commands in the Nextcloud and database  containers to
# generate the snapshots. Also, because Nextcloud has to be put in maintenance
# mode to create a consistent backup, care has been given to make sure that the
# maintenance window is short as possible. Backups as saved under /var/backups
# which should be a Docker volume.

alias nc_run='docker exec -u www-data nextcloud-nextcloud-1'
alias db_run='docker exec -u nobody nextcloud-mysql-1'

cleanup () {
    nc_run php occ maintenance:mode --off
    nc_run rm -rf "$tmpdir"
}

now="$(date --utc -Iseconds)"
dest="/var/backups/$now"
mkdir "$dest"

trap 'cleanup' INT QUIT EXIT TERM
tmpdir="$(basename "$(nc_run mktemp --directory --tmpdir=.)")"
nc_run php occ maintenance:mode --on

nc_run find -maxdepth 1 -mindepth 1 \! -name "$tmpdir" -exec \
    cp --archive --reflink=always "--target=$tmpdir" {} \; &

# shellcheck disable=SC2016
db_run sh -c \
    'mysqldump --single-transaction --default-character-set=utf8mb4 --routines --add-drop-database --force "--password=$MYSQL_ROOT_PASSWORD" --user=root --databases "$MYSQL_DATABASE"' | \
    zstd -o "$dest/mysqldump.sql.zstd" &

wait
nc_run php occ maintenance:mode --off

nc_run tar -c "$tmpdir" | zstd -o "$dest/nextcloud_volume.tar.zstd"
