Add database backup script

Add scripts/backup-db.sh for backing up the embedded PostgreSQL database
with support for custom (.dump) and plain SQL formats, auto-detection of
the configured port, and pruning of backups older than 30 days.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Forgotten
2026-02-19 13:11:26 -06:00
parent 6adc453068
commit 61db74d525
2 changed files with 86 additions and 0 deletions

View File

@@ -13,6 +13,7 @@
"test:run": "vitest run", "test:run": "vitest run",
"db:generate": "pnpm --filter @paperclip/db generate", "db:generate": "pnpm --filter @paperclip/db generate",
"db:migrate": "pnpm --filter @paperclip/db migrate", "db:migrate": "pnpm --filter @paperclip/db migrate",
"db:backup": "./scripts/backup-db.sh",
"paperclip": "node cli/node_modules/tsx/dist/cli.mjs cli/src/index.ts" "paperclip": "node cli/node_modules/tsx/dist/cli.mjs cli/src/index.ts"
}, },
"devDependencies": { "devDependencies": {

85
scripts/backup-db.sh Executable file
View File

@@ -0,0 +1,85 @@
#!/usr/bin/env bash
set -euo pipefail
# Backup the embedded PostgreSQL database to data/backups/
#
# Usage:
# ./scripts/backup-db.sh # default: custom format (.dump)
# ./scripts/backup-db.sh --sql # plain SQL format (.sql)
#
# Requires: pg_dump (brew install postgresql)
# The embedded postgres must be running (start with: pnpm dev)
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
BACKUP_DIR="$PROJECT_ROOT/data/backups"
# Read config for port, fall back to default
PORT=54329
CONFIG_FILE="$PROJECT_ROOT/.paperclip/config.json"
if [ -f "$CONFIG_FILE" ]; then
CONFIGURED_PORT=$(python3 -c "
import json, sys
try:
c = json.load(open('$CONFIG_FILE'))
print(c.get('database', {}).get('embeddedPostgresPort', ''))
except: pass
" 2>/dev/null || true)
if [ -n "$CONFIGURED_PORT" ]; then
PORT="$CONFIGURED_PORT"
fi
fi
DB_NAME="paperclip"
DB_USER="paperclip"
DB_HOST="127.0.0.1"
# Check pg_dump is available
if ! command -v pg_dump &>/dev/null; then
echo "Error: pg_dump not found. Install with: brew install postgresql" >&2
exit 1
fi
# Check the database is reachable
if ! PGPASSWORD="$DB_USER" pg_isready -h "$DB_HOST" -p "$PORT" -U "$DB_USER" &>/dev/null; then
echo "Error: Cannot connect to embedded PostgreSQL on port $PORT." >&2
echo " Make sure the server is running (pnpm dev)." >&2
exit 1
fi
mkdir -p "$BACKUP_DIR"
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
# Choose format
FORMAT="custom"
EXT="dump"
if [[ "${1:-}" == "--sql" ]]; then
FORMAT="plain"
EXT="sql"
fi
BACKUP_FILE="$BACKUP_DIR/paperclip-${TIMESTAMP}.${EXT}"
echo "Backing up database '$DB_NAME' on port $PORT..."
PGPASSWORD="$DB_USER" pg_dump \
-h "$DB_HOST" \
-p "$PORT" \
-U "$DB_USER" \
-d "$DB_NAME" \
--format="$FORMAT" \
--file="$BACKUP_FILE"
SIZE=$(du -h "$BACKUP_FILE" | cut -f1)
echo "Backup saved: $BACKUP_FILE ($SIZE)"
# Prune backups older than 30 days
PRUNED=0
find "$BACKUP_DIR" -name "paperclip-*" -mtime +30 -type f -print0 | while IFS= read -r -d '' old; do
rm "$old"
PRUNED=$((PRUNED + 1))
done
if [ "$PRUNED" -gt 0 ]; then
echo "Pruned $PRUNED backup(s) older than 30 days."
fi