Sk1-exam/scripts/backup.sh
Gigi Saji 260b60622f Initial commit: Expense Tracker on Oracle Cloud (sk1 exam)
Public-cloud deployment of a single-user expense tracker:
- 4-container stack: Caddy (HTTPS via Let's Encrypt), nginx (React/Vite SPA), Express API, Postgres 16
- Repeatable deployment via prepare-app.sh using only OCI CLI (no web console)
- Persistent Postgres volume, auto-restart policies, healthchecks, backup + restore scripts
- DuckDNS dynamic DNS for the public hostname; secrets isolated to gitignored .env

Author: Gigi Saji
Live URL: https://savesave.duckdns.org
2026-05-14 12:53:45 +05:30

47 lines
1.9 KiB
Bash

#!/usr/bin/env bash
# =============================================================================
# backup.sh — dump the Postgres database to ./backups/expenses-<ts>.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)"