Бэкап RAG-platform — runbook (RAG-05)¶
Цель: ежедневный консистентный бэкап всего RAG-стека на ragserver:
Postgres (метаданные OpenWebUI), Qdrant (векторные эмбеддинги),
OpenWebUI data (файлы/аттачменты/uploads), .env, docker-compose.yml.
Если ragserver упадёт — все Knowledge collections, файлы, эмбеддинги можно поднять на новом железе за ~30 минут.
Технология:
- Postgres: pg_dump --format=custom — консистентный дамп даже при живой БД
- Qdrant: POST /collections/{col}/snapshots — атомарный snapshot всей коллекции
- OpenWebUI data: обычный tar -czf (файлы читаются, не пишутся во время бэкапа обычно)
- Всё вместе → tar → GPG AES-256 → ретеншн 14 дней
Итоговый архив ~сотни MB (в зависимости от объёма knowledge). GPG-пароль тот же что для Vaultwarden и AmneziaWG.
Шаг 1 · Подготовить окружение на ragserver¶
# На ragserver (192.168.1.200), от oswold:
mkdir -p /home/oswold/backups/rag-platform
chmod 700 /home/oswold/backups /home/oswold/backups/rag-platform
# GPG passfile — тот же пароль что в /root/.vw_backup_pass на VPS
# Скопируй значение с VPS (SSH туда, cat /root/.vw_backup_pass, сохрани сюда):
touch /home/oswold/.rag_backup_pass
chmod 600 /home/oswold/.rag_backup_pass
# Вставь пароль:
echo 'PASTE_THE_SAME_GPG_PASSPHRASE_HERE' > /home/oswold/.rag_backup_pass
Проверка что gnupg установлен:
Шаг 2 · Установить скрипт¶
# На ragserver:
mkdir -p /opt/rag-platform/backups
cd /opt/rag-platform/backups
# Скачать (репо приватный — либо через github CLI, либо scp с локали):
scp <твоя_локальная_машина>:/tmp/alatyr-infra-kb/skeletons/backup-rag-platform.sh ./
# Или после того как ты клонируешь alatyr-infra-kb на ragserver:
# cp /path/to/alatyr-infra-kb/skeletons/backup-rag-platform.sh ./
chmod 700 backup-rag-platform.sh
⚠️ Внутри скрипта строка sudo tar -czf ... openwebui требует sudo без пароля.
Вариант A — добавить в sudoers для oswold (безопаснее, ограничить только этой командой):
Внутри:oswold ALL=(root) NOPASSWD: /bin/tar -czf /tmp/rag_staging_*/openwebui-data.tar.gz -C /opt/rag-platform/data openwebui
oswold ALL=(root) NOPASSWD: /bin/cp /opt/rag-platform/.env /tmp/rag_staging_*/env
oswold ALL=(root) NOPASSWD: /bin/cp /opt/rag-platform/docker-compose.yml /tmp/rag_staging_*/docker-compose.yml
oswold ALL=(root) NOPASSWD: /bin/chown oswold\:oswold /tmp/rag_staging_*/env /tmp/rag_staging_*/docker-compose.yml
Вариант B — прогонять cron от root вместо oswold (проще, но root-cron):
Мы выбираем вариант B для простоты (cron уже под root на VPS для Vaultwarden — тот же паттерн).
Шаг 3 · Первый ручной прогон¶
# От root:
sudo /opt/rag-platform/backups/backup-rag-platform.sh
sudo tail -50 /home/oswold/backups/rag-backup.log
Ожидание в логе:
[2026-08-08 04:00:12] [1/5] Postgres dump
[2026-08-08 04:00:14] Postgres dump: 1234567 байт
[2026-08-08 04:00:14] [2/5] Qdrant snapshots
[2026-08-08 04:00:15] Snapshot коллекции: alatyr-infra-kb
[2026-08-08 04:00:18] Snapshot коллекции: personal
[2026-08-08 04:00:20] [3/5] OpenWebUI data
[2026-08-08 04:00:35] OpenWebUI data: 234567890 байт
[2026-08-08 04:00:36] [4/5] Конфиги
[2026-08-08 04:00:36] [5/5] Архивирую и шифрую
[2026-08-08 04:01:12] Зашифрованный: .../rag-backup-*.tar.gz.gpg (234567891 байт)
[2026-08-08 04:01:12] OK: 1 архивов, суммарно 224M
Быстрая проверка:
sudo ls -lh /home/oswold/backups/rag-platform/
sudo file /home/oswold/backups/rag-platform/*.gpg
# ожидание: GPG symmetrically encrypted data (AES256)
Шаг 4 · Cron¶
Добавить:
# Бэкап RAG-platform (RAG-05). 04:00 MSK — после Vaultwarden/AmneziaWG
0 4 * * * /opt/rag-platform/backups/backup-rag-platform.sh >/dev/null 2>&1
Проверить:
Шаг 5 · Test restore (обязательно, разово)¶
Проверить что бэкап реально можно раскатать.
# На тестовой машине или /tmp:
mkdir -p /tmp/rag-restore-test && cd /tmp/rag-restore-test
sudo cp /home/oswold/backups/rag-platform/rag-backup-*.gpg ./
# 1. GPG-расшифровка
sudo gpg --decrypt --passphrase-file /home/oswold/.rag_backup_pass \
--batch --output rag-restore.tar.gz \
rag-backup-*.gpg
# 2. Распаковать
sudo tar -tzf rag-restore.tar.gz | head -20
# Ожидание: postgres-*.dump, qdrant/, openwebui-data.tar.gz, env, docker-compose.yml, metadata.txt
sudo tar -xzf rag-restore.tar.gz -C ./
ls -la
# 3. Postgres dump — проверка структуры (не восстанавливаем в БД)
sudo pg_restore --list postgres-*.dump | head -30
# Ожидание: список таблиц OpenWebUI (auth, chat, document, file, ...)
# 4. Qdrant snapshot — проверка что файл валидный tar
sudo tar -tzf qdrant/*__*.snapshot 2>&1 | head -5 || \
sudo file qdrant/*__*
# Snapshot Qdrant — это tar внутри (Qdrant формат), проверить размер >0
sudo rm -rf /tmp/rag-restore-test
Если всё расшифровалось и структуры целые → ✅ бэкап рабочий.
Как восстановить RAG-platform из бэкапа (disaster recovery)¶
Сценарий: новый ragserver или severe corruption.
- Установить Docker + Docker Compose + gnupg.
- Расшифровать самый свежий бэкап:
- Восстановить
.envиdocker-compose.yml: - Восстановить OpenWebUI data:
- Стартануть Postgres и Qdrant (без OpenWebUI пока):
- Восстановить Postgres:
- Восстановить Qdrant snapshots (для каждой коллекции):
QDRANT_KEY=$(grep QDRANT_API_KEY .env | cut -d= -f2) for snap in restore/qdrant/*; do col=$(basename "$snap" | cut -d_ -f1) # Upload snapshot в Qdrant curl -X POST -H "api-key: $QDRANT_KEY" \ "http://localhost:6333/collections/${col}/snapshots/upload" \ -F "snapshot=@$snap" # Восстановить из snapshot curl -X PUT -H "api-key: $QDRANT_KEY" \ "http://localhost:6333/collections/${col}/snapshots/recover" \ -d "{\"location\": \"file://$snap\"}" done - Стартовать OpenWebUI:
- Проверить https://rag.alatyr-service.ru — все коллекции и файлы на месте.
Ожидаемое время disaster recovery: 30-45 минут на всё.
Off-site sync?¶
RAG-платформа сама уже "off-site" от VPS. Но если хочется дублирования на VPS (или на облачное хранилище) — открытый вопрос:
- Архивы могут быть сотни MB — 1 GB. VPS Hostkey vm-mini имеет ограниченное место.
- Если решим — тот же паттерн что offsite.sh, но в обратную сторону (VPS pull-ит).
- Альтернатива: Yandex S3 (glacier-tier, ~$5/мес за 100GB), rclone.
Пока — retention 14 дней локально на ragserver достаточно. Проработать этот вопрос отдельной задачей когда бэкапы стабилизируются.
Мониторинг¶
# Через 2 дня проверить логи:
sudo tail -100 /home/oswold/backups/rag-backup.log
# Ожидание: 2 записи "OK" с ростом счётчика архивов
# Размер бэкапов:
sudo du -sh /home/oswold/backups/rag-platform/
Uptime Kuma (задача 28) — push-monitor из скрипта после успеха.
Диагностика¶
| Симптом | Причина | Действия |
|---|---|---|
pg_dump: connection refused |
Postgres контейнер упал | docker ps, docker logs rag-postgres |
Qdrant snapshot 500 |
Qdrant OOM или диск полный | docker stats rag-qdrant, df -h /opt/rag-platform |
| Архивы становятся всё больше | Уплотнение не работает | Проверить RAG_EMBEDDING_MODEL — не сменилась ли на большую |
gpg: no passphrase given |
passfile отсутствует | Пересоздать /home/oswold/.rag_backup_pass |
Автор: агент, 08.08.2026