Бэкап: полный оффсайт-бэкап прода на 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:
2026-06-26 23:36:58 +03:00
co-authored by Claude Opus 4.8
parent 1e19038b7c
commit 32c74abc43
6 changed files with 155 additions and 17 deletions
+20 -2
View File
@@ -38,8 +38,26 @@ git pull
docker compose up -d --build
```
## Бэкап БД
`scripts/backup.sh` (консистентная онлайн-копия SQLite; по cron на хосте). Том БД — `db-data`.
## Бэкап (полный + оффсайт на VPS)
`scripts/backup.sh` делает консистентный онлайн-снимок и собирает **полный** архив
`fs_<TS>.tar.gz` (БД + `uploads/` + `achievements/`) в `backups/` с ротацией. Если в `.env`
задан `BACKUP_VPS_HOST` — копия дополнительно уходит на VPS (оффсайт; Pi → VPS push, т.к. CGNAT).
Настройка оффсайта (один раз):
```bash
# 1) отдельный ключ бэкапа + его pubkey на VPS (юзер backup — см. deploy/vps/README.md):
ssh-keygen -t ed25519 -f deploy/backup/id_backup -N ""
ssh-copy-id -i deploy/backup/id_backup.pub backup@186.246.51.17
# 2) в .env заполнить BACKUP_VPS_HOST=186.246.51.17 (по желанию — BACKUP_VPS_USER/DIR/KEEP_*)
# 3) разовый прогон и проверка, что архив доехал на VPS:
scripts/backup.sh
# 4) cron (ежедневно в 04:00):
crontab -e
# 0 4 * * * /home/pi/ForbidenStarsApp/scripts/backup.sh >> /var/log/fs-backup.log 2>&1
```
Восстановление: `scripts/restore.sh backups/fs_<TS>.tar.gz` (ДЕСТРУКТИВНО — заменяет текущие
данные; сначала проверь на тест-контуре). Тома — `db-data` / `uploads-data` / `achievements-data`.
Логи: `docker compose logs -f app` / `... tunnel`. Если `https://forbiddenstars.ru` отдаёт
502 — значит туннель не поднят: смотри `docker compose logs tunnel` (чаще всего ключ не в