Files
sp/scripts/restore-drill.sh
Semih 909cacf7b3 feat(phase4): rate limit + audit archive + panel backup + DR docs
- src/lib/rate-limit.ts (Redis sliding window, fail-open)
- before-hook on /sign-in/email: 5 attempts/min per IP+email
- worker job audit-archive (daily 03:30, JSONL → MinIO, 90d retention)
- worker job panel-backup (daily 04:00, pg_dump -Fc -Z9 → MinIO)
- Dockerfile adds postgresql16-client
- scripts/restore-drill.sh restores latest dump into panel_drill
- docs/disaster-recovery.md + docs/phase4-deferred.md (mTLS + Infisical rationale)
2026-05-13 11:14:36 +00:00

58 lines
2.6 KiB
Bash
Executable File

#!/usr/bin/env bash
# Restore drill: pulls the latest panel-postgres dump from MinIO and restores
# into a throwaway "panel_drill" database, then runs a few SELECT sanity checks.
#
# Run on the maestro host. Requires: docker (with access to coolify-db + minio-global).
#
# Usage:
# ./scripts/restore-drill.sh # latest dump
# ./scripts/restore-drill.sh 2026-05-13T03-00-00 # specific key prefix
set -euo pipefail
MINIO_CT=${MINIO_CT:-minio-global}
PG_CT=${PG_CT:-coolify-db}
BUCKET=${MINIO_BACKUP_BUCKET:-panel-backups}
PREFIX=${1:-}
DRILL_DB=${DRILL_DB:-panel_drill}
if ! sudo docker ps --format '{{.Names}}' | grep -q "^${MINIO_CT}$"; then
echo "minio container '${MINIO_CT}' not running" >&2
exit 1
fi
ROOT_USER=$(sudo docker exec "$MINIO_CT" sh -c 'echo $MINIO_ROOT_USER')
ROOT_PASS=$(sudo docker exec "$MINIO_CT" sh -c 'echo $MINIO_ROOT_PASSWORD')
echo "==> finding latest dump in $BUCKET/panel-postgres/"
sudo docker exec "$MINIO_CT" sh -c "mc alias set local http://localhost:9000 '$ROOT_USER' '$ROOT_PASS' >/dev/null" || true
LATEST=$(sudo docker exec "$MINIO_CT" sh -c "mc ls --recursive local/$BUCKET/panel-postgres/ 2>/dev/null | sort | tail -1 | awk '{print \$NF}'")
[ -n "$LATEST" ] || { echo "no dumps found" >&2; exit 1; }
echo "==> latest: $LATEST"
TMP=$(mktemp /tmp/panel-drill.XXXXXX.dump)
trap 'rm -f "$TMP"' EXIT
echo "==> downloading…"
sudo docker exec "$MINIO_CT" sh -c "mc cp local/$BUCKET/panel-postgres/$LATEST /tmp/drill.dump >/dev/null"
sudo docker cp "$MINIO_CT":/tmp/drill.dump "$TMP"
sudo docker exec "$MINIO_CT" rm -f /tmp/drill.dump || true
echo "==> dropping + recreating $DRILL_DB on $PG_CT"
sudo docker exec "$PG_CT" psql -U coolify -d postgres -c "DROP DATABASE IF EXISTS $DRILL_DB;" >/dev/null
sudo docker exec "$PG_CT" psql -U coolify -d postgres -c "CREATE DATABASE $DRILL_DB OWNER coolify;" >/dev/null
echo "==> pg_restoring…"
sudo docker cp "$TMP" "$PG_CT":/tmp/drill.dump
sudo docker exec "$PG_CT" pg_restore --clean --if-exists -U coolify -d "$DRILL_DB" /tmp/drill.dump
sudo docker exec "$PG_CT" rm -f /tmp/drill.dump
echo "==> sanity checks"
sudo docker exec "$PG_CT" psql -U coolify -d "$DRILL_DB" -c '\dt'
sudo docker exec "$PG_CT" psql -U coolify -d "$DRILL_DB" -c 'SELECT count(*) FROM "User";'
sudo docker exec "$PG_CT" psql -U coolify -d "$DRILL_DB" -c 'SELECT count(*) FROM "Project";'
sudo docker exec "$PG_CT" psql -U coolify -d "$DRILL_DB" -c 'SELECT count(*) FROM "AuditLog";'
echo "==> drill OK. Drop the drill DB when done:"
echo " sudo docker exec $PG_CT psql -U coolify -d postgres -c 'DROP DATABASE $DRILL_DB;'"