Бэкап: полный оффсайт-бэкап прода на VPS (БД + uploads + achievements) + восстановление
- scripts/backup.sh: консистентный снимок SQLite (.backup) + архив fs_<TS>.tar.gz с uploads и achievements в backups/, локальная ротация; при заданном BACKUP_VPS_HOST — push на VPS (scp отдельным ключом/юзером) с удалённой ротацией. Настройки читаются из .env (BACKUP_*). - scripts/restore.sh: восстановление архива в прод (stop app → очистка тома → docker cp → start). - .env.example: блок BACKUP_* (host/user/dir/key/keep). .gitignore: id_backup* (ключ бэкапа). - deploy/pi/README, deploy/vps/README: настройка ключа и юзера backup, /srv/fs-backups, cron, restore. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Executable
+47
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env bash
|
||||
# Восстановление прода из архива бэкапа (fs_<TS>.tar.gz): БД + uploads + achievements.
|
||||
# ДЕСТРУКТИВНО — заменяет текущие данные тома. Сначала проверьте на тест-контуре!
|
||||
# Использование:
|
||||
# scripts/restore.sh backups/fs_YYYYmmdd_HHMMSS.tar.gz [--yes]
|
||||
set -euo pipefail
|
||||
|
||||
PROJECT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
COMPOSE="docker compose -f $PROJECT_DIR/docker-compose.yml"
|
||||
SERVICE="app"
|
||||
|
||||
ARCHIVE="${1:-}"
|
||||
CONFIRM="${2:-}"
|
||||
if [ -z "$ARCHIVE" ] || [ ! -f "$ARCHIVE" ]; then
|
||||
echo "Использование: $0 <путь к fs_*.tar.gz> [--yes]" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ "$CONFIRM" != "--yes" ]; then
|
||||
printf "ВНИМАНИЕ: текущие БД/uploads/achievements будут заменены из %s\nПродолжить? [y/N] " "$ARCHIVE"
|
||||
read -r ans
|
||||
case "$ans" in y|Y|yes|да|Да) ;; *) echo "Отменено."; exit 1 ;; esac
|
||||
fi
|
||||
|
||||
STAGE="$(mktemp -d)"
|
||||
trap 'rm -rf "$STAGE"' EXIT
|
||||
tar -xzf "$ARCHIVE" -C "$STAGE"
|
||||
if [ ! -f "$STAGE/forbidden_stars.db" ]; then
|
||||
echo "ОШИБКА: в архиве нет forbidden_stars.db." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[restore] Остановка приложения…"
|
||||
$COMPOSE stop "$SERVICE"
|
||||
|
||||
echo "[restore] Очистка тома (старая БД, WAL/SHM, медиа, титулы)…"
|
||||
$COMPOSE run --rm --no-deps -T --entrypoint sh "$SERVICE" -c \
|
||||
"rm -f /data/forbidden_stars.db /data/forbidden_stars.db-wal /data/forbidden_stars.db-shm; rm -rf /data/uploads/* /data/achievements/*"
|
||||
|
||||
CID="$($COMPOSE ps -aq "$SERVICE")"
|
||||
echo "[restore] Запись данных в контейнер…"
|
||||
docker cp "$STAGE/forbidden_stars.db" "$CID:/data/forbidden_stars.db"
|
||||
[ -d "$STAGE/uploads" ] && docker cp "$STAGE/uploads/." "$CID:/data/uploads"
|
||||
[ -d "$STAGE/achievements" ] && docker cp "$STAGE/achievements/." "$CID:/data/achievements"
|
||||
|
||||
echo "[restore] Запуск приложения…"
|
||||
$COMPOSE start "$SERVICE"
|
||||
echo "[restore] Готово. Проверьте https://forbiddenstars.ru и логи: $COMPOSE logs -f app"
|
||||
Reference in New Issue
Block a user