#!/usr/bin/env bash # ============================================================================= # backup.sh — dump the Postgres database to ./backups/expenses-.sql.gz # # Run from your laptop. Requires .env (for OCI_VM_NAME and SSH key) and # uses the OCI CLI to look up the VM's public IP. # ============================================================================= set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" cd "$ROOT_DIR" [ -f .env ] || { echo "ERROR: .env not found"; exit 1; } set -a; source .env; set +a : "${OCI_VM_NAME:=sk1-expense-tracker}" : "${POSTGRES_USER:?POSTGRES_USER must be set in .env}" : "${POSTGRES_DB:?POSTGRES_DB must be set in .env}" : "${OCI_SSH_PRIVATE_KEY_PATH:=$HOME/.ssh/id_ed25519}" OCI_SSH_PRIVATE_KEY_PATH="${OCI_SSH_PRIVATE_KEY_PATH/#\~/$HOME}" TENANCY_OCID="$(oci iam compartment list --query 'data[0]."compartment-id"' --raw-output 2>/dev/null)" COMPARTMENT_ID="${OCI_COMPARTMENT_ID:-$TENANCY_OCID}" INSTANCE_ID="$(oci compute instance list --compartment-id "$COMPARTMENT_ID" \ --display-name "$OCI_VM_NAME" --lifecycle-state RUNNING \ --query 'data[0].id' --raw-output)" [ -n "$INSTANCE_ID" ] && [ "$INSTANCE_ID" != "null" ] || { echo "ERROR: VM not found"; exit 1; } VNIC_ID="$(oci compute instance list-vnics --instance-id "$INSTANCE_ID" --query 'data[0].id' --raw-output)" PUBLIC_IP="$(oci network vnic get --vnic-id "$VNIC_ID" --query 'data."public-ip"' --raw-output)" mkdir -p backups TS="$(date +%Y%m%d-%H%M%S)" OUT="backups/expenses-${TS}.sql.gz" echo "[backup] dumping $POSTGRES_DB from $PUBLIC_IP..." ssh -i "$OCI_SSH_PRIVATE_KEY_PATH" -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ ubuntu@"$PUBLIC_IP" \ "sg docker -c 'docker exec sk1-db pg_dump -U $POSTGRES_USER -Fc $POSTGRES_DB'" \ | gzip > "$OUT" SIZE="$(du -h "$OUT" | cut -f1)" echo "[backup] saved $OUT ($SIZE)"