#!/bin/sh # Offline backup of the live MRPGI vault — the accounts (argon2 hashes) and # saved worlds that ONLY exist on the dealgod VPS and are NOT in git. # # Pulls /opt/mrpgi-vault/data down to this machine as a timestamped tarball, # keeping the 30 most recent snapshots. Run it from anywhere. # # ./mrpgi-vault/backup.sh # MRPGI_BACKUP_DIR=/some/where ./mrpgi-vault/backup.sh # override location # # Restore onto the VPS (if the box is ever rebuilt): # tar -xzf vault-YYYYMMDD-HHMMSS.tar.gz # gives ./data # scp -r data root@100.94.195.115:/opt/mrpgi-vault/ # ssh root@100.94.195.115 'docker restart mrpgi-vault' # # Scheduled daily on the ultra via a launchd LaunchAgent: # ~/Library/LaunchAgents/games.monsterrobot.vault-backup.plist (fires 4am) # NOTE: launchd can't execute scripts inside ~/Documents (macOS TCC blocks it), # so the job runs a COPY at "~/Library/Application Support/mrpgi/backup.sh". # After editing this file, resync that copy: # cp mrpgi-vault/backup.sh ~/Library/"Application Support"/mrpgi/backup.sh # Manage the job: # launchctl kickstart -k gui/$(id -u)/games.monsterrobot.vault-backup # run now # launchctl bootout gui/$(id -u)/games.monsterrobot.vault-backup # stop it set -e REMOTE="${MRPGI_VAULT_REMOTE:-root@100.94.195.115:/opt/mrpgi-vault/data}" DEST="${MRPGI_BACKUP_DIR:-$HOME/MRPGI-vault-backups}" KEEP=30 mkdir -p "$DEST" STAMP=$(date +%Y%m%d-%H%M%S) TMP=$(mktemp -d) trap 'rm -rf "$TMP"' EXIT scp -q -r "$REMOTE" "$TMP/data" tar -czf "$DEST/vault-$STAMP.tar.gz" -C "$TMP" data # prune to the newest $KEEP snapshots ls -1t "$DEST"/vault-*.tar.gz 2>/dev/null | tail -n +$((KEEP + 1)) | while read -r old; do rm -f "$old"; done COUNT=$(ls -1 "$DEST"/vault-*.tar.gz 2>/dev/null | wc -l | tr -d ' ') SIZE=$(du -h "$DEST/vault-$STAMP.tar.gz" | cut -f1) echo "backed up -> $DEST/vault-$STAMP.tar.gz ($SIZE; $COUNT snapshots kept)"