#!/usr/bin/env bash # tools/cmd/railiance-backup — backup custodian state to Nextcloud file drop set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" source "${ROOT}/lib/railiance-print.sh" # ── Configuration ───────────────────────────────────────────────────────────── AGE_PUBLIC_KEY="age1zvryunvjhvpkmasskauga2heeg0ztnte9ymgppvjge36ekumk50syr3tsz" NC_WEBDAV_URL="https://nx4069.your-storageshare.de/public.php/webdav" NC_TOKEN="MfTBEjcJTGS8Ywo" PG_CONTAINER="infra-postgres-1" PG_USER="custodian" PG_DB="custodian" BACKUP_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/railiance/backups" TS="$(date -u +%Y%m%dT%H%M%SZ)" # ── Helpers ─────────────────────────────────────────────────────────────────── nc_upload() { local file="$1" name="$2" curl -sf -u "${NC_TOKEN}:" -T "$file" "${NC_WEBDAV_URL}/${name}" \ || { bad "upload" "failed to upload ${name}"; exit 1; } } # ── Main ────────────────────────────────────────────────────────────────────── mkdir -p "$BACKUP_DIR" print_hdr "Railiance Backup — ${TS}" # 1. PostgreSQL ok "postgres" "dumping ${PG_DB}…" TMP_DB="${BACKUP_DIR}/db-${TS}.sql.age" docker exec "${PG_CONTAINER}" pg_dump -U "${PG_USER}" "${PG_DB}" \ | age -r "${AGE_PUBLIC_KEY}" -o "${TMP_DB}" ok "postgres" "encrypted → $(basename "$TMP_DB")" nc_upload "${TMP_DB}" "db-${TS}.sql.age" ok "postgres" "uploaded to Nextcloud" # 2. Config snapshot ok "config" "snapshotting ~/.claude/ ~/.claude.json .gitconfig…" TMP_CFG_TAR="${BACKUP_DIR}/config-${TS}.tar.gz" TMP_CFG="${BACKUP_DIR}/config-${TS}.tar.gz.age" tar -czf "${TMP_CFG_TAR}" \ -C "$HOME" \ --ignore-failed-read \ .claude \ .claude.json \ .gitconfig \ 2>/dev/null || true age -r "${AGE_PUBLIC_KEY}" -o "${TMP_CFG}" "${TMP_CFG_TAR}" rm -f "${TMP_CFG_TAR}" ok "config" "encrypted → $(basename "$TMP_CFG")" nc_upload "${TMP_CFG}" "config-${TS}.tar.gz.age" ok "config" "uploaded to Nextcloud" # 3. Prune local cache (keep last 7 of each type) find "${BACKUP_DIR}" -name "db-*.sql.age" | sort -r | tail -n +8 | xargs -r rm -f find "${BACKUP_DIR}" -name "config-*.tar.gz.age" | sort -r | tail -n +8 | xargs -r rm -f ok "cache" "local copies pruned (keep last 7)" # 4. Write stamp (preflight reads this) echo "${TS}" > "${BACKUP_DIR}/.last-backup" echo ok "done" "Backup complete — ${TS}" echo " DB: db-${TS}.sql.age" echo " Config: config-${TS}.tar.gz.age" echo echo " ⚠️ The age private key at ~/.config/age/railiance-backup.key" echo " MUST also be stored in your password manager or written down." echo " Without it you cannot decrypt these backups."