Резервное копирование и восстановление
Резервное копирование и восстановление
Стратегия
| Тип | Частота | Хранение | Место |
|---|---|---|---|
| Ежедневный (daily) | 03:00 UTC+5 | 7 дней | Yandex Object Storage |
| Еженедельный (weekly) | Воскресенье 03:00 | 4 недели | Yandex Object Storage |
| Шифрование | GPG AES-256 | — | 152-ФЗ: ПД в дампах |
Дамп создаётся через pg_dump → сжатие gzip → шифрование GPG → загрузка в S3.
Настройка бэкапа
1. Переменные окружения
Убедитесь, что в .env.prod заданы:
YC_BUCKET_NAME=terma-grand-backupsYC_ACCESS_KEY_ID=<ключ сервисного аккаунта>YC_SECRET_ACCESS_KEY=<секрет>YC_REGION=ru-central1S3_ENDPOINT=https://storage.yandexcloud.netBACKUP_GPG_PASSPHRASE=<сильный пароль шифрования>2. Создать S3 bucket
# Через YC CLIyc storage bucket create \ --name terma-grand-backups \ --default-storage-class STANDARD
# Настроить private accessyc storage bucket update \ --name terma-grand-backups \ --public-read false \ --public-list false3. Ручной запуск бэкапа
# Загрузить переменныеsource /opt/terma-grand/repo/.env.prod
# Запуститьbash /opt/terma-grand/repo/scripts/deploy/backup.shЛоги:
[2026-04-22 03:00:01] [BACKUP] ========== BACKUP START: 20260422_030001 ==========[2026-04-22 03:00:01] [BACKUP] Starting pg_dump → /tmp/terma-backups/terma_prod_20260422_030001.sql.gz[2026-04-22 03:00:05] [BACKUP] Dump complete: 1.2M[2026-04-22 03:00:05] [BACKUP] Encrypting dump with GPG...[2026-04-22 03:00:05] [BACKUP] Upload complete: s3://terma-grand-backups/pg/daily/terma_prod_20260422_030001.sql.gz.gpg[2026-04-22 03:00:06] [BACKUP] Rotation complete[2026-04-22 03:00:06] [BACKUP] ========== BACKUP SUCCESS ==========4. Cron-расписание
crontab -e
# Ежедневно в 03:00 (UTC+5 = 22:00 UTC)0 22 * * * source /opt/terma-grand/repo/.env.prod && \ bash /opt/terma-grand/repo/scripts/deploy/backup.sh \ >> /var/log/terma-grand-backup.log 2>&1Структура в Object Storage
terma-grand-backups/└── pg/ ├── daily/ │ ├── terma_prod_20260421_220001.sql.gz.gpg │ ├── terma_prod_20260422_220001.sql.gz.gpg │ └── ... (7 файлов) └── weekly/ ├── terma_prod_20260419_220001.sql.gz.gpg └── ... (4 файла)Восстановление из бэкапа
⚠️ ВНИМАНИЕ: Восстановление перезаписывает текущую базу данных. Выполнять только при DR или плановой миграции.
1. Просмотр доступных бэкапов
source /opt/terma-grand/repo/.env.prod
AWS_ACCESS_KEY_ID="${YC_ACCESS_KEY_ID}" \AWS_SECRET_ACCESS_KEY="${YC_SECRET_ACCESS_KEY}" \aws s3 ls s3://terma-grand-backups/pg/daily/ \ --endpoint-url https://storage.yandexcloud.net \ | sort2. Восстановление из S3
source /opt/terma-grand/repo/.env.prod
bash /opt/terma-grand/repo/scripts/deploy/restore.sh \ --from "s3://terma-grand-backups/pg/daily/terma_prod_20260421_220001.sql.gz.gpg"Скрипт попросит подтверждение, затем:
- Скачает файл из S3
- Дешифрует GPG
- Остановит app и bot
- Восстановит базу через
psql - Запустит сервисы
- Выполнит healthcheck
3. Восстановление из локального файла
bash /opt/terma-grand/repo/scripts/deploy/restore.sh \ --from /tmp/terma_prod_20260421.sql.gz.gpg4. Dry-run (без изменений)
bash /opt/terma-grand/repo/scripts/deploy/restore.sh \ --from "s3://..." \ --dry-runПроверка бэкапа (тест восстановления)
Рекомендуется ежемесячная проверка работоспособности дампа:
# 1. Скачать последний дамп# 2. Дешифроватьgpg --batch --passphrase "${BACKUP_GPG_PASSPHRASE}" \ --decrypt dump.sql.gz.gpg | zcat | head -50
# 3. Восстановить на тестовую базу (не prod)docker exec -i repo-postgres-1 \ psql -U terma -d postgres -c "CREATE DATABASE terma_test_restore;"
zcat dump.sql.gz | docker exec -i repo-postgres-1 \ psql -U terma -d terma_test_restore
# 4. Проверить количество записейdocker exec repo-postgres-1 \ psql -U terma -d terma_test_restore -c "SELECT COUNT(*) FROM users;"
# 5. Удалить тестовую базуdocker exec repo-postgres-1 \ psql -U terma -d postgres -c "DROP DATABASE terma_test_restore;"