Настройка бэкапа (#64) #66

Merged
NotBigGhost merged 5 commits from issue-64-backup into dev 2026-09-14 17:54:01 +03:00
5 Commits
Author SHA1 Message Date
NotBigGhostandClaude Opus 5 8b400b76c6 Бэкап: убрать старые backup.sh/restore.sh, документация
deploy/backup/README.md — подробная пошаговая инструкция по всему, что делается вручную:
пароль шифрования, SSH-ключ, VPS (пользователь fsbackup только для SFTP, проверки sshd),
сборка образов, включение на Pi (с разбором каждой переменной и контрольными проверками),
доступ с ПК и выгрузка, учебное восстановление на тест-клоне, восстановление прода и из
архива, катастрофа «Pi умер», повседневные действия, таблица неполадок, справочник, чек-лист.
Команды разделов VPS и Pi прогнаны на локальном стенде.
deploy/pi, deploy/vps §8, deploy/README — ссылки на новую схему. Удалены scripts/backup.sh и
scripts/restore.sh (restore.sh ещё и оставлял БД root-овой: docker cp пишет файлы с uid 0);
их архивы fs_*.tar.gz восстанавливаются через fs-backup import. #64

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jBxs9nBCk5nBdTLzcGz91
2026-09-14 01:29:08 +03:00
NotBigGhostandClaude Opus 5 19f6068ddc Бэкап: защита истории от пустых данных
run отказывается бэкапить БД без игроков и партий, если последний снимок в репозитории был
с данными: новый Pi до восстановления иначе отправил бы пустой снимок на VPS, он стал бы
latest, а keep-daily мог вытеснить настоящий снимок того же дня. Обход — run --allow-empty.
Очистка дополнительно всегда оставляет 3 последних снимка. Проверено сценарием «Pi умер»:
отказ бэкапа → restore latest --repo vps → следующий бэкап проходит. #64

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jBxs9nBCk5nBdTLzcGz91
2026-09-14 01:29:08 +03:00
NotBigGhostandClaude Opus 5 d764ff86d3 Бэкап: скрипты управления с ПК
scripts/fs-backup.ps1 (ASCII, Windows PowerShell 5.1) и scripts/fs-backup.sh (Linux/macOS/
Git Bash) — одинаковые команды к контейнеру backup прода на Pi по SSH или к локальному
тест-клону (-Target test / --test): status, list, now [--tag], verify;
pull — export в файл на Pi, scp в backups/, сверка sha256 и проверка содержимого tar
(бинарные данные не идут через пайпы PowerShell — они их портят);
restore-test — учебное восстановление архива (в т.ч. старого fs_*.tar.gz) в тест-клон.
Настройки BACKUP_PI_SSH / BACKUP_PI_DIR из .env, переменная окружения важнее.
Вызовы нативных команд устойчивы к перенаправлению stderr в PS 5.1. #64

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jBxs9nBCk5nBdTLzcGz91
2026-09-14 01:12:41 +03:00
NotBigGhostandClaude Opus 5 e2d729d339 Бэкап: сервис backup в compose прода и тест-клона, .env.example
docker-compose.yml: сервис backup (образ из реестра, явный environment только с BACKUP_*,
тома данных + backup-data), предупреждение про down -v. docker-compose.test.yml: тот же
образ локальной сборкой, только локальный репозиторий, без расписания, BACKUP_VPS_HOST
принудительно пуст. .env.example: новый блок BACKUP_* (пароль, расписание, хранение,
сжатие, SFTP-пользователь fsbackup — системный backup в Debian/Ubuntu уже занят, ключ
base64, адрес Pi для скриптов ПК); удалены BACKUP_VPS_KEY и BACKUP_KEEP_LOCAL/REMOTE.
build-push: сообщения про третий образ (bake подхватывает сервис сам). #64

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jBxs9nBCk5nBdTLzcGz91
2026-09-14 01:04:12 +03:00
NotBigGhostandClaude Opus 5 f73316f37f Бэкап: образ restic-сайдкара и скрипт fs-backup
deploy/backup: образ на restic/restic:0.19.1 (+ sqlite, supercronic, tini), работает от
uid 10001, как appuser. Скрипт fs-backup:
- run: консистентная копия БД (VACUUM INTO + integrity_check), снимок в локальный
  репозиторий и на VPS (SFTP), теги players/matches, GFS-очистка (дни/недели/месяцы;
  именованные keep и pre-restore не удаляются), restic check;
- list / status / verify / export (tar без сжатия; сжатие — только restic, репозиторий v2);
- restore / import через промежуточную директорию: разворачивание в .restore-new внутри
  каждого тома, проверка (integrity_check, таблицы, число файлов, целостность tar),
  страховочный снимок pre-restore, двухфазная замена rename с файлом фазы и откатом;
  recover разбирает прерванное восстановление. Отказ при работающем app.
Точка входа: без BACKUP_PASSWORD простой без рестарт-петли, первый снимок при пустом
репозитории, расписание supercronic, healthcheck по возрасту последнего успеха. #64

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jBxs9nBCk5nBdTLzcGz91
2026-09-14 01:04:12 +03:00