Files
ZBrain/docs/OPERATIONS.md
T
zuevav f4bca8449e main
2026-05-20 19:33:02 +03:00

11 KiB
Raw Blame History

Operations Guide

Документ для оператора ZBrain (admin) — повседневные задачи, типовые проблемы, runbook.

Чек-лист после деплоя

После завершения 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)

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):

sudo docker exec zbrain-api node -e '
  // TODO: команда будет добавлена в Sprint 7
'

Создать новый брейн

sudo bash /opt/zbrain/scripts/create-brain.sh <name> "<display name>" <port>

# Пример
sudo bash /opt/zbrain/scripts/create-brain.sh fontvielle "Fontvielle Infrastructure" 3005

Импорт большого корпуса в брейн

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 доступом):

    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. Останавливаем все брейны:

    sudo systemctl stop 'zbrain-gbrain-*'
    
  5. Обновляем gbrain:

    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. Применяем миграции каждого брейна:

    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. Запускаем брейны:

    sudo systemctl start 'zbrain-gbrain-*'
    
  8. Проверяем health.

Восстановление из бэкапа

См. scripts/restore.sh. Краткая инструкция:

sudo bash /opt/zbrain/scripts/restore.sh 20260520-031500
# спросит путь к age приватному ключу

ВАЖНО: после restore удалить age ключ с VM:

shred -u /tmp/backup.age

Реактивация заблокированного пользователя

Если пользователь забыл пароль или нужно сбросить:

-- Через UI пока нет, делаем напрямую
sudo -u postgres psql -d brainhub

-- Сгенерировать новый bcrypt hash (cost=12)
-- Можно через: echo 'newpassword' | htpasswd -bnBC 12 "" -
UPDATE users
SET password_hash = '<new-bcrypt-hash>',
    must_change_password = true
WHERE email = 'user@example.com';

Срочный отзыв токена

Если подозрение на утечку токена и нельзя ждать 30 секунд кэша:

# Через UI: /tokens → Revoke. Это уже делает invalidate cache.

# Срочное через API:
curl -X POST http://brain.zetit.local/api/admin/cache/invalidate-token \
  -H "Authorization: Bearer <admin-session-token>" \
  -H "Content-Type: application/json" \
  -d '{"tokenPrefix":"brain_pat_a8f3"}'

# Полный сброс кэша токенов (drastic):
sudo systemctl restart docker
sudo docker compose restart brainhub-api

Мониторинг

Что смотреть в /var/log/zbrain/

# 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

# 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

# По брейнам
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 брейн помечен красным.

# 1. Проверить systemd unit
sudo systemctl status zbrain-gbrain-<brain>

# 2. Если down - последние логи
sudo journalctl -u zbrain-gbrain-<brain> -n 100 --no-pager

# 3. Если crash loop - проверить Postgres connection
sudo -u postgres psql -d gbrain_<brain> -c 'SELECT version()'

# 4. Если ОК - перезапустить
sudo systemctl restart zbrain-gbrain-<brain>

# 5. Если не помогло - временно отключить и эскалировать
sudo systemctl stop zbrain-gbrain-<brain>

Сценарий: Postgres недоступен

Симптомы: brainhub возвращает 503, все брейны лежат.

# 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.

# Проверка через 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

Сценарий: подозрение на утечку токена

# 1. Найти токен в UI: /tokens → найти по prefix
# 2. Посмотреть активность: /audit?actor_type=token&actor_id=<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='<token-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 при необходимости