# Operations Guide Документ для оператора ZBrain (admin) — повседневные задачи, типовые проблемы, runbook. ## Чек-лист после деплоя После завершения [DEPLOYMENT.md](DEPLOYMENT.md): - [ ] Все systemd unit'ы для брейнов активны: `systemctl status 'zbrain-gbrain-*'` - [ ] Docker контейнеры brainhub запущены: `docker compose -f /opt/zbrain/deploy/docker/docker-compose.yml ps` - [ ] Nginx обслуживает оба домена: `curl -H "Host: brain.zetit.local" http://localhost/health` - [ ] Cron для backup'ов настроен: `sudo crontab -l | grep backup` - [ ] Логи пишутся: `ls -lh /var/log/zbrain/` - [ ] Disk usage в норме: `df -h /var/lib/postgresql /var/lib/zbrain /var/log` ## Ежедневные задачи (автоматические) ### Backup (cron, 03:00) ```cron 0 3 * * * root /opt/zbrain/scripts/backup.sh ``` Что проверять раз в неделю: - `ls -lh /var/backups/zbrain/` — есть свежий бэкап - `cat /var/log/zbrain/backup.log | tail -20` — нет ошибок - Раз в месяц — тестовое восстановление на отдельной VM ### Sync (опционально, cron, 06:00 / 18:00) Если источники не настроены через UI с расписанием, можно запускать вручную через scripts/sync-all.sh (будет добавлено в Sprint 4). ## Типовые задачи ### Создать нового пользователя Через UI: 1. Залогинься как owner 2. /users → New user 3. Email + role (admin / editor / viewer) 4. Скопировать temp password из ответа Через CLI (только owner): ```bash sudo docker exec zbrain-api node -e ' // TODO: команда будет добавлена в Sprint 7 ' ``` ### Создать новый брейн ```bash sudo bash /opt/zbrain/scripts/create-brain.sh "" # Пример sudo bash /opt/zbrain/scripts/create-brain.sh fontvielle "Fontvielle Infrastructure" 3005 ``` ### Импорт большого корпуса в брейн ```bash sudo -u zbrain bash -c ' export PATH=$HOME/.bun/bin:$PATH source /etc/zbrain/.env export DATABASE_URL=$(cat /var/lib/zbrain/brains/zetit/config.json | jq -r .database_url) cd /var/lib/zbrain/gbrain bun run gbrain import /path/to/markdown/ ' ``` Для очень больших корпусов (>10000 страниц) — лучше через UI после Sprint 4, там SSE прогресс. ### Обновить gbrain до новой версии 1. **На рабочей машине** (с GitHub доступом): ```bash git clone --bare https://github.com/garrytan/gbrain.git cd gbrain.git git push --mirror git@git.zetit.ru:zuevav/gbrain-mirror.git ``` 2. **На VM ZBrain** — проверить changelog upstream'а на breaking changes, особенно в БД схеме. 3. Создать ADR в `docs/DECISIONS/` если есть значимые изменения. 4. Останавливаем все брейны: ```bash sudo systemctl stop 'zbrain-gbrain-*' ``` 5. Обновляем gbrain: ```bash sudo -u zbrain bash -c ' cd /var/lib/zbrain/gbrain git fetch git checkout v0.27.0 # новая версия export PATH=$HOME/.bun/bin:$PATH export HTTPS_PROXY=$(grep HTTPS_PROXY /etc/zbrain/.env | cut -d= -f2-) bun install ' ``` 6. Применяем миграции каждого брейна: ```bash for brain in zetit telerapharma personal community; do sudo -u zbrain bash -c " export PATH=\$HOME/.bun/bin:\$PATH export DATABASE_URL=\$(cat /var/lib/zbrain/brains/$brain/config.json | jq -r .database_url) cd /var/lib/zbrain/gbrain bun run gbrain migrate " done ``` 7. Запускаем брейны: ```bash sudo systemctl start 'zbrain-gbrain-*' ``` 8. Проверяем health. ### Восстановление из бэкапа См. `scripts/restore.sh`. Краткая инструкция: ```bash sudo bash /opt/zbrain/scripts/restore.sh 20260520-031500 # спросит путь к age приватному ключу ``` **ВАЖНО:** после restore удалить age ключ с VM: ```bash shred -u /tmp/backup.age ``` ### Реактивация заблокированного пользователя Если пользователь забыл пароль или нужно сбросить: ```sql -- Через UI пока нет, делаем напрямую sudo -u postgres psql -d brainhub -- Сгенерировать новый bcrypt hash (cost=12) -- Можно через: echo 'newpassword' | htpasswd -bnBC 12 "" - UPDATE users SET password_hash = '', must_change_password = true WHERE email = 'user@example.com'; ``` ### Срочный отзыв токена Если подозрение на утечку токена и нельзя ждать 30 секунд кэша: ```bash # Через UI: /tokens → Revoke. Это уже делает invalidate cache. # Срочное через API: curl -X POST http://brain.zetit.local/api/admin/cache/invalidate-token \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{"tokenPrefix":"brain_pat_a8f3"}' # Полный сброс кэша токенов (drastic): sudo systemctl restart docker sudo docker compose restart brainhub-api ``` ## Мониторинг ### Что смотреть в /var/log/zbrain/ ```bash # Live tail всех логов sudo tail -F /var/log/zbrain/*.log # Ошибки за последний час sudo journalctl --since "1 hour ago" -u 'zbrain-gbrain-*' | grep -i error # Brainhub access pattern sudo tail -1000 /var/log/zbrain/brainhub.log | jq -r 'select(.req.url) | "\(.time) \(.req.method) \(.req.url) → \(.res.statusCode)"' ``` ### Метрики Postgres ```bash # Connection count sudo -u postgres psql -c 'SELECT count(*), state FROM pg_stat_activity GROUP BY state;' # Размер БД sudo -u postgres psql -c " SELECT datname, pg_size_pretty(pg_database_size(datname)) FROM pg_database WHERE datname IN ('brainhub','gbrain_zetit','gbrain_telerapharma','gbrain_personal','gbrain_community') ORDER BY pg_database_size(datname) DESC; " # Топ медленных запросов sudo -u postgres psql -c ' SELECT calls, mean_exec_time, query FROM pg_stat_statements ORDER BY mean_exec_time DESC LIMIT 10; ' # если pg_stat_statements включён ``` ### Disk usage ```bash # По брейнам du -sh /var/lib/zbrain/brains/*/ # Postgres data sudo du -sh /var/lib/postgresql/16/main/ # Логи sudo du -sh /var/log/zbrain/ /var/log/postgresql/ /var/log/nginx/ ``` Если /var/log пухнет — настроить logrotate. ## Runbook'и инцидентов ### Сценарий: брейн не отвечает на MCP запросы **Симптомы:** Claude Code получает 502 от /mcp/, в UI брейн помечен красным. ```bash # 1. Проверить systemd unit sudo systemctl status zbrain-gbrain- # 2. Если down - последние логи sudo journalctl -u zbrain-gbrain- -n 100 --no-pager # 3. Если crash loop - проверить Postgres connection sudo -u postgres psql -d gbrain_ -c 'SELECT version()' # 4. Если ОК - перезапустить sudo systemctl restart zbrain-gbrain- # 5. Если не помогло - временно отключить и эскалировать sudo systemctl stop zbrain-gbrain- ``` ### Сценарий: Postgres недоступен **Симптомы:** brainhub возвращает 503, все брейны лежат. ```bash # 1. Статус sudo systemctl status postgresql # 2. Если crashed - проверить логи sudo tail -200 /var/log/postgresql/postgresql-16-main.log # 3. Частые причины: # a) Disk full → освободить место (старые WAL, логи) df -h /var/lib/postgresql sudo du -sh /var/lib/postgresql/16/main/pg_wal/ # b) OOM → проверить dmesg sudo dmesg | tail -50 | grep -i 'killed process' # c) Corrupt → restore из бэкапа ``` ### Сценарий: исчерпался лимит OpenAI/Anthropic API **Симптомы:** sync падает с 429, новые pages не получают embeddings. ```bash # Проверка через FNA прокси sudo -u zbrain bash -c ' source /etc/zbrain/.env curl --proxy "$HTTPS_PROXY" \ https://api.openai.com/v1/dashboard/billing/usage \ -H "Authorization: Bearer $OPENAI_API_KEY" ' # Действия: # 1. Пополнить баланс на платформе OpenAI/Anthropic # 2. Или временно поставить на паузу автоматический sync # 3. Прикинуть стоимость re-embed: ~$0.65 на 7500 страниц для text-embedding-3-large ``` ### Сценарий: подозрение на утечку токена ```bash # 1. Найти токен в UI: /tokens → найти по prefix # 2. Посмотреть активность: /audit?actor_type=token&actor_id= # 3. Revoke + invalidate cache # 4. Создать новый токен с теми же scope, передать пользователю # 5. Анализ через audit log: sudo -u postgres psql -d brainhub -c " SELECT created_at, ip, action, payload FROM audit_log WHERE actor_type='token' AND actor_id='' ORDER BY created_at DESC LIMIT 100; " # 6. Если был доступ из неожиданного IP - эскалация (анализ что было прочитано/изменено) ``` ## Регулярные процедуры ### Раз в неделю - Проверить freshness бэкапов и логи backup.log - Проверить disk usage - Глянуть audit log на необычную активность ### Раз в месяц - Тестовый restore на отдельной VM - Review обновлений gbrain upstream - Обновить ОС (`apt update && apt upgrade`) - Rotate session secrets (опционально, но повышает security posture) ### Раз в квартал - Penetration test публичного контура (хотя бы на nikto/zap-baseline) - Review активных токенов, удаление неиспользуемых - Review активных пользователей, удаление неактивных - Capacity planning: смотреть рост БД и проектировать апгрейд VM при необходимости