Files
argento/scripts/backup.sh
T
2026-04-14 16:06:03 -04:00

55 lines
1.9 KiB
Bash
Executable File

#!/bin/bash
# Daily USB backup. Dumps DBs for consistency, then rsyncs everything.
set -euo pipefail
FAILURES=()
# Check the USB drive is actually mounted
if ! mountpoint -q /mnt/backup; then
echo "FATAL: /mnt/backup is not mounted" >&2
exit 1
fi
# Dump Nextcloud PostgreSQL for consistency
if docker exec nextcloud-db pg_dumpall -U nextcloud > /opt/argento/docker/nextcloud/db/pg_dumpall.sql.tmp; then
mv /opt/argento/docker/nextcloud/db/pg_dumpall.sql.tmp /opt/argento/docker/nextcloud/db/pg_dumpall.sql
else
rm -f /opt/argento/docker/nextcloud/db/pg_dumpall.sql.tmp
FAILURES+=("nextcloud pg_dump")
fi
# Dump Immich PostgreSQL for consistency
mkdir -p /opt/argento/docker/immich/db
IMMICH_DB_USER=$(grep -E '^DB_USERNAME=' /opt/argento/docker/immich/.env | cut -d= -f2)
if docker exec immich_postgres pg_dumpall -U "${IMMICH_DB_USER:-postgres}" > /opt/argento/docker/immich/db/pg_dumpall.sql.tmp; then
mv /opt/argento/docker/immich/db/pg_dumpall.sql.tmp /opt/argento/docker/immich/db/pg_dumpall.sql
else
rm -f /opt/argento/docker/immich/db/pg_dumpall.sql.tmp
FAILURES+=("immich pg_dump")
fi
# Dump Gitea SQLite for consistency
sqlite3 /opt/argento/docker/gitea/data/gitea/gitea.db \
".backup /opt/argento/docker/gitea/data/gitea/gitea.db.bak" \
|| FAILURES+=("gitea sqlite backup")
# Dump Jellyfin SQLite DBs for consistency
for db in jellyfin library; do
sqlite3 /opt/argento/docker/jellyfin/config/data/${db}.db \
".backup /opt/argento/docker/jellyfin/config/data/${db}.db.bak" \
|| FAILURES+=("jellyfin ${db} sqlite backup")
done
# Single rsync covers everything: configs, app data, media, DB dumps
RSYNC_OPTS="-a --delete"
[ -t 1 ] && RSYNC_OPTS="$RSYNC_OPTS --info=progress2"
rsync $RSYNC_OPTS /opt/argento/ /mnt/backup/argento/ \
|| FAILURES+=("rsync argento")
if [ ${#FAILURES[@]} -gt 0 ]; then
echo "BACKUP FAILED: ${FAILURES[*]}" >&2
exit 1
fi
echo "Backup completed successfully at $(date)"