Add Kopia backup stack with Backblaze B2 offsite target.

Protects /config, selective labdata, and nightly DB dumps; documents homelab improvement plan briefs.
This commit is contained in:
ginnoir
2026-06-10 21:21:34 -05:00
parent 225078afbe
commit 7c7f6dfebc
47 changed files with 3105 additions and 1 deletions
@@ -0,0 +1,51 @@
#!/bin/sh
# Dump all homelab databases to /config/backup/dumps (gzip SQL).
# Runs inside backup_scheduler; needs docker.sock.
set -eu
DUMP_ROOT=/dumps
STAMP=$(date +%Y%m%d-%H%M%S)
DIR="${DUMP_ROOT}/${STAMP}"
mkdir -p "${DIR}"
log() { echo "[backup-dump ${STAMP}] $*"; }
dump_postgres() {
name="$1"
user="$2"
db="$3"
if ! docker ps --format '{{.Names}}' | grep -qx "${name}"; then
log "skip ${name} (not running)"
return 0
fi
log "dump ${name}${db}"
docker exec "${name}" pg_dump -U "${user}" "${db}" | gzip -c > "${DIR}/${name}.sql.gz"
}
dump_mariadb() {
name="$1"
db="$2"
if ! docker ps --format '{{.Names}}' | grep -qx "${name}"; then
log "skip ${name} (not running)"
return 0
fi
log "dump ${name}${db}"
docker exec "${name}" sh -c "mariadb-dump -u root -p\"\$MYSQL_ROOT_PASSWORD\" \"${db}\"" \
| gzip -c > "${DIR}/${name}.sql.gz"
}
log "starting database dumps → ${DIR}"
dump_postgres postgres_gitea gitea gitea
dump_postgres postgres_plane plane plane
dump_postgres postgres_authentik authentik authentik
dump_postgres postgres_famapp famapp famapp
dump_postgres postgres_resume postgres postgres
dump_mariadb mariadb_bookstack bookstack
dump_mariadb owncloud_mariadb owncloud
dump_mariadb romm-db romm
find "${DUMP_ROOT}" -mindepth 1 -maxdepth 1 -type d -mtime +14 -exec rm -rf {} + 2>/dev/null || true
log "done"
@@ -0,0 +1,33 @@
#!/bin/sh
set -eu
[ -f /etc/backup.env ] && . /etc/backup.env
NTFY_URL="${NTFY_URL:-https://ntfy.ginnoir.com/backup}"
NTFY_TITLE="${NTFY_TITLE:-ValhallaBackup}"
notify() {
priority="$1"
message="$2"
curl -sf -H "Title: ${NTFY_TITLE}" -H "Priority: ${priority}" -d "${message}" "${NTFY_URL}" >/dev/null 2>&1 || true
}
if ! docker ps --format '{{.Names}}' | grep -qx kopia; then
notify high "Kopia container not running — snapshots skipped"
exit 1
fi
FAILED=0
while IFS= read -r path || [ -n "${path}" ]; do
case "${path}" in ''|\#*) continue ;; esac
if ! docker exec kopia kopia snapshot create "${path}"; then
FAILED=1
fi
done < /snapshot-paths.txt
if [ "${FAILED}" -eq 0 ]; then
notify default "Snapshots OK ($(date +%Y-%m-%d\ %H:%M))"
else
notify high "One or more snapshots FAILED — check docker logs kopia"
exit 1
fi