Task 60 — Postgres backups: - deploy/backups/: backup.sh (pg_dump -Fc nightly), retain.sh (14/8/6 tiers), restore.sh, entrypoint.sh, crontab - famapp-backup Alpine service + backups volume added to deploy/compose.yaml - Restore procedure in deploy/backups/README.md Task 61 — Rate limiting on share links: - src/lib/rate-limit.ts: Edge-compatible sliding-window counter (50/min, LRU eviction) with consume(), isRateLimited(), recordFailure() exports - middleware.ts: enforces 429 with Retry-After: 60 for /s/[token] (IP + token prefix) - /s/[token]/page.tsx: tracks only failed resolveShareToken calls via recordFailure() Task 62 — Structured logging: - pino + pino-pretty installed; serverExternalPackages added to next.config.ts - src/lib/logger.ts: JSON in production, pretty in dev, level from LOG_LEVEL env - middleware.ts: structured JSON request log (method, path, status, ms, authenticated) - _core/push.ts, notify.ts, reminders.ts: console.error/log → logger.error/info Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
59 lines
1.5 KiB
Bash
59 lines
1.5 KiB
Bash
#!/bin/sh
|
|
# Nightly pg_dump for famapp-db and authentik-db.
|
|
# Called by crond. Outputs to /backups/<db>/daily/<YYYY-MM-DD>.dump
|
|
# and copies into weekly/ (Sundays) and monthly/ (1st of month).
|
|
set -eu
|
|
|
|
TODAY=$(date +%Y-%m-%d)
|
|
DOW=$(date +%u) # 1=Mon … 7=Sun
|
|
DOM=$(date +%d | sed 's/^0*//') # day-of-month without leading zero
|
|
|
|
dump_db() {
|
|
local name="$1"
|
|
local host="$2"
|
|
local port="$3"
|
|
local user="$4"
|
|
local pass="$5"
|
|
local dbname="$6"
|
|
|
|
local daily_dir="/backups/$name/daily"
|
|
local dest="$daily_dir/$TODAY.dump"
|
|
|
|
mkdir -p "$daily_dir" \
|
|
"/backups/$name/weekly" \
|
|
"/backups/$name/monthly"
|
|
|
|
echo "[backup] dumping $name ..."
|
|
PGPASSWORD="$pass" pg_dump \
|
|
-h "$host" -p "$port" -U "$user" -d "$dbname" \
|
|
-Fc -f "$dest"
|
|
echo "[backup] $name → $dest"
|
|
|
|
if [ "$DOW" = "7" ]; then
|
|
cp "$dest" "/backups/$name/weekly/$TODAY.dump"
|
|
echo "[backup] weekly copy saved for $name"
|
|
fi
|
|
|
|
if [ "$DOM" = "1" ]; then
|
|
cp "$dest" "/backups/$name/monthly/$TODAY.dump"
|
|
echo "[backup] monthly copy saved for $name"
|
|
fi
|
|
}
|
|
|
|
dump_db famapp \
|
|
"${FAMAPP_DB_HOST:-famapp-db}" \
|
|
"${FAMAPP_DB_PORT:-5432}" \
|
|
"$FAMAPP_DB_USER" \
|
|
"$FAMAPP_DB_PASSWORD" \
|
|
"$FAMAPP_DB_NAME"
|
|
|
|
dump_db authentik \
|
|
"${AUTHENTIK_DB_HOST:-authentik-db}" \
|
|
"${AUTHENTIK_DB_PORT:-5432}" \
|
|
"$AUTHENTIK_DB_USER" \
|
|
"$AUTHENTIK_DB_PASSWORD" \
|
|
"$AUTHENTIK_DB_NAME"
|
|
|
|
/scripts/retain.sh
|
|
echo "[backup] complete"
|