feat(ops): обязательный backup БД и файлов перед деплоем

This commit is contained in:
2026-10-26 15:47:22 +03:00
parent de9535d35c
commit 7c45de8d9f
9 changed files with 447 additions and 12 deletions

114
deploy/BACKUP.md Normal file
View File

@@ -0,0 +1,114 @@
# Резервное копирование LMS
Резервное копирование обязательно:
- **перед каждым обновлением** (`./deploy/deploy.sh up` делает backup автоматически);
- **ежедневно** по расписанию (systemd timer);
- перед миграциями и любыми ручными изменениями схемы/данных.
## Что входит в backup
Один каталог `backups/lms-<UTC timestamp>/`:
| Файл | Содержимое |
|---|---|
| `db.dump` | `pg_dump --format=custom` всей БД `lms` |
| `submissions.tar.gz` | volume `lms_lms_submissions` — решения студентов |
| `assets.tar.gz` | volume `lms_lms_assets` — файлы материалов |
| `SHA256SUMS` | контрольные суммы |
| `manifest.txt` | дата, БД, пользователь, проект, retention |
Каталоги бэкапов создаются с правами `700`: внутри персональные данные.
## Настройки
В `.env.prod`:
```dotenv
LMS_BACKUP_DIR=/opt/lms/backups
LMS_BACKUP_KEEP_DAYS=14
```
`LMS_BACKUP_KEEP_DAYS` — сколько дней хранить. `0` отключает автоудаление.
## Ручные команды
```bash
./deploy/backup.sh backup # создать backup
./deploy/backup.sh backup --if-running # пропустить, если стек не запущен
./deploy/backup.sh list # список backup-каталогов
./deploy/backup.sh verify <dir> # проверить суммы и целостность
./deploy/backup.sh restore <dir> # восстановить (destructive)
```
`restore` требует ввести `RESTORE`, останавливает прикладные сервисы,
пересоздаёт БД, восстанавливает файлы и поднимает стек. PostgreSQL при этом
не удаляется.
## Автоматически перед обновлением
`deploy/deploy.sh up` вызывает:
```bash
./deploy/backup.sh backup --if-running
```
Если стек ещё не запущен (первый деплой), шаг пропускается. Если backup
завершился ошибкой — деплой прерывается.
## Ежедневное расписание (systemd)
```bash
sudo cp deploy/systemd/lms-backup.service /etc/systemd/system/
sudo cp deploy/systemd/lms-backup.timer /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now lms-backup.timer
systemctl list-timers lms-backup.timer
```
По умолчанию — каждый день в 03:00 с разбросом до 30 минут. `Persistent=true`
означает, что пропущенный запуск выполнится после включения сервера.
Если systemd недоступен, cron:
```cron
0 3 * * * cd /opt/lms && ./deploy/backup.sh backup >>/var/log/lms-backup.log 2>&1
```
## Восстановление
```bash
./deploy/backup.sh verify /opt/lms/backups/lms-20261023T030000Z
./deploy/backup.sh restore /opt/lms/backups/lms-20261023T030000Z
```
Проверка после восстановления:
```bash
./deploy/deploy.sh ps
curl -fsS http://127.0.0.1:8090/actuator/health
```
## Внешняя копия
Backup на том же сервере не защищает от потери сервера. Настройте выгрузку:
```bash
rsync -a --delete /opt/lms/backups/ backup-host:/srv/lms-backups/
```
Требования:
- шифрование при передаче и хранении (backups содержат ПДн);
- отдельный хост/хранилище;
- проверка восстановления не реже раза в месяц на staging;
- не хранить backup в git и в каталоге проекта без `.gitignore`.
## Проверка
Минимум раз в месяц:
1. `./deploy/backup.sh verify <dir>`.
2. Развернуть копию на staging.
3. Восстановить БД и файлы.
4. Проверить вход, группу, лабу, сдачу и скачивание файла.