#!/usr/bin/env bash # backup.sh — manual backup of a service # Usage: just backup supabase # Uploads a timestamped dump to Backblaze B2. set -euo pipefail SERVICE="${1:-supabase}" TIMESTAMP=$(date -u +"%Y%m%dT%H%M%SZ") BACKUP_DIR="${BACKUP_DIR:-/tmp/colectivo-backups}" mkdir -p "$BACKUP_DIR" case "$SERVICE" in supabase|postgres|db) DUMP_FILE="$BACKUP_DIR/postgres-$TIMESTAMP.dump" echo "==> Dumping PostgreSQL → $DUMP_FILE" docker compose -f "$(dirname "$0")/../docker-compose.prod.yml" exec -T db \ pg_dumpall -U postgres --clean --if-exists \ | gzip > "$DUMP_FILE.gz" DUMP_FILE="$DUMP_FILE.gz" ;; keycloak) DUMP_FILE="$BACKUP_DIR/keycloak-$TIMESTAMP.json" echo "==> Exporting Keycloak realm → $DUMP_FILE" docker compose -f "$(dirname "$0")/../docker-compose.prod.yml" exec keycloak \ /opt/keycloak/bin/kc.sh export \ --realm colectivo \ --users realm_file \ --file /tmp/kc-export.json docker compose -f "$(dirname "$0")/../docker-compose.prod.yml" cp \ keycloak:/tmp/kc-export.json "$DUMP_FILE" gzip "$DUMP_FILE" DUMP_FILE="$DUMP_FILE.gz" ;; *) echo "Unknown service: $SERVICE. Use 'supabase' or 'keycloak'." >&2 exit 1 ;; esac echo "==> Uploading $(basename "$DUMP_FILE") to B2 bucket: ${B2_BUCKET_NAME}" b2 file upload \ --contentType application/octet-stream \ "$B2_BUCKET_NAME" \ "$DUMP_FILE" \ "backups/$(basename "$DUMP_FILE")" echo "==> Backup complete: $(basename "$DUMP_FILE")" rm -f "$DUMP_FILE"