Skip to main content

max / makenotwork

2.5 KB · 68 lines History Blame Raw
1 #!/bin/bash
2 # Sync database backups to offsite host (astra) via Tailscale.
3 # Called by backup-db.sh after each successful backup.
4 #
5 # Setup on astra:
6 # mkdir -p /opt/backups/mnw
7 #
8 # Setup on Hetzner (as makenotwork user):
9 # Ensure SSH key-based auth to astra is configured:
10 # ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N ""
11 # ssh-copy-id max@100.106.221.39
12 # Test: ssh max@100.106.221.39 "echo ok"
13
14 set -euo pipefail
15
16 OFFSITE_HOST="100.106.221.39" # astra (Tailscale IP)
17 OFFSITE_USER="max"
18 OFFSITE_DIR="/opt/backups/mnw"
19 BACKUP_DIR="/opt/makenotwork/backups"
20 DB_NAME="makenotwork"
21 OFFSITE_RETENTION_DAYS=30
22 WAM_URL="${WAM_URL:-http://127.0.0.1:7890}"
23
24 # Open a WAM ticket for offsite backup failures.
25 wam_alert() {
26 local title="$1"
27 local body="${2:-}"
28 curl -sf -X POST "$WAM_URL/tickets" \
29 -H "Content-Type: application/json" \
30 -d "{\"title\": \"$title\", \"body\": \"$body\", \"priority\": \"high\", \"source\": \"backup-offsite\"}" \
31 >/dev/null 2>&1 || true
32 }
33
34 # Find the most recent backup
35 LATEST=$(ls -t "${BACKUP_DIR}/${DB_NAME}"-*.sql.gz 2>/dev/null | head -1)
36 if [ -z "$LATEST" ]; then
37 echo "[$(date -Iseconds)] OFFSITE: No backups found to sync"
38 exit 0
39 fi
40
41 echo "[$(date -Iseconds)] OFFSITE: Syncing $(basename "$LATEST") to ${OFFSITE_HOST}:${OFFSITE_DIR}"
42
43 # Transfer with compression (already gzipped, so -z won't help much, but
44 # rsync handles partial transfers and resume on failure)
45 if rsync -e "ssh -o ConnectTimeout=10 -o StrictHostKeyChecking=accept-new" \
46 --timeout=120 \
47 "$LATEST" \
48 "${OFFSITE_USER}@${OFFSITE_HOST}:${OFFSITE_DIR}/"; then
49 echo "[$(date -Iseconds)] OFFSITE: Transfer complete"
50 else
51 echo "[$(date -Iseconds)] OFFSITE: Transfer FAILED (astra unreachable or SSH error)"
52 wam_alert "Offsite backup sync failed" "rsync to ${OFFSITE_HOST}:${OFFSITE_DIR} failed for $(basename "$LATEST"). Check Tailscale connectivity and SSH auth."
53 exit 0
54 fi
55
56 # Prune old offsite backups
57 DELETED=$(ssh -o ConnectTimeout=10 "${OFFSITE_USER}@${OFFSITE_HOST}" \
58 "find ${OFFSITE_DIR} -name '${DB_NAME}-*.sql.gz' -mtime +${OFFSITE_RETENTION_DAYS} -delete -print 2>/dev/null | wc -l" \
59 2>/dev/null || echo "0")
60 if [ "$DELETED" -gt 0 ]; then
61 echo "[$(date -Iseconds)] OFFSITE: Pruned ${DELETED} backup(s) older than ${OFFSITE_RETENTION_DAYS} days"
62 fi
63
64 TOTAL=$(ssh -o ConnectTimeout=10 "${OFFSITE_USER}@${OFFSITE_HOST}" \
65 "ls ${OFFSITE_DIR}/${DB_NAME}-*.sql.gz 2>/dev/null | wc -l" \
66 2>/dev/null || echo "?")
67 echo "[$(date -Iseconds)] OFFSITE: Total backups on astra: ${TOTAL}"
68