Files
zuevav f4bca8449e main
2026-05-20 19:33:02 +03:00

320 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 <name> "<display name>" <port>
# Пример
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 = '<new-bcrypt-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 <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/
```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/<brain>, в UI брейн помечен красным.
```bash
# 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, все брейны лежат.
```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=<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 при необходимости