project-bifrost-platform/scripts/backup.sh
Arlind 819f8fa91c feat(deploy): nginx reverse-proxy deploy setup for bifrost-portal.fenja.ai
Run the Astro Node standalone server as a hardened systemd service on
127.0.0.1:4322, behind the existing nginx which terminates TLS and proxies
the bifrost-portal.fenja.ai hostname. Coexists with the other Fenja site;
its config is untouched.

- deploy/bifrost-portal.service: systemd unit (bifrost user, EnvironmentFile,
  ProtectSystem, ReadWritePaths to the data dir only)
- deploy/nginx/bifrost-portal.fenja.ai.conf: HTTP->HTTPS + proxy site block
- .env.production.example: prod env vars (secret, db path, uploads, host/port)
- scripts/deploy.sh: server-side pull -> install (rebuild native dep) ->
  build -> migrate -> restart; persistent data untouched
- scripts/backup.sh: nightly online .backup, 30-day retention
- DEPLOY.md: full runbook (port check, DNS, provision, TLS, backups, rollback)

Persistent data (db, uploads, backups) lives in /var/lib/bifrost-portal,
outside the /opt/bifrost-portal build dir, so redeploys never wipe it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 12:54:35 +02:00

32 lines
1 KiB
Bash
Executable file

#!/usr/bin/env bash
#
# Nightly SQLite backup for the Bifrost portal. Uses the online .backup API
# (safe while the app is running — consistent, no locking issues with WAL).
# Keeps 30 days of compressed snapshots.
#
# Install as a cron job (as the `bifrost` user):
# crontab -e
# 15 3 * * * /opt/bifrost-portal/scripts/backup.sh >> /var/log/bifrost-backup.log 2>&1
#
# Per SPEC §7.3 the offsite target is a Hetzner Storage Box; sync BACKUP_DIR
# there separately (e.g. rclone/rsync in a second cron line).
set -euo pipefail
DB_PATH="${BIFROST_DB_PATH:-/var/lib/bifrost-portal/bifrost.db}"
BACKUP_DIR="${BACKUP_DIR:-/var/lib/bifrost-portal/backups}"
RETENTION_DAYS="${RETENTION_DAYS:-30}"
mkdir -p "$BACKUP_DIR"
stamp="$(date -u +%Y%m%d-%H%M%S)"
out="$BACKUP_DIR/bifrost-$stamp.db"
echo "==> Backing up $DB_PATH -> $out"
sqlite3 "$DB_PATH" ".backup '$out'"
gzip -f "$out"
echo "==> Pruning backups older than $RETENTION_DAYS days"
find "$BACKUP_DIR" -name 'bifrost-*.db.gz' -type f -mtime "+$RETENTION_DAYS" -delete
echo "==> Backup complete: ${out}.gz"