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

10 KiB
Raw Permalink Blame History

Deployment Guide

Полная инструкция по развёртыванию ZBrain с нуля.

Стадия 1: Подготовка VM

Спецификация

Параметр Значение
ОС Ubuntu 22.04 LTS Server
CPU 4 vCPU (минимум 2)
RAM 8 GB (минимум 4)
Disk 80 GB SSD (минимум 40)
FS ext4
Network статический IP в сети ZETIT

Создание

  1. На гипервизоре создать VM с указанными параметрами
  2. Установить Ubuntu 22.04 LTS Server (minimal)
  3. Создать пользователя admin с sudo правами
  4. Скопировать SSH-ключи: ssh-copy-id admin@<ip>
  5. Отключить password auth: sudo passwd -l root и в /etc/ssh/sshd_config PasswordAuthentication no

Базовая конфигурация

# Hostname
sudo hostnamectl set-hostname zbrain
echo "127.0.1.1 zbrain.zetit.local zbrain" | sudo tee -a /etc/hosts

# Часовой пояс
sudo timedatectl set-timezone Europe/Moscow

# Обновления
sudo apt-get update && sudo apt-get upgrade -y
sudo apt-get install -y unattended-upgrades

DNS

В твоей внутренней DNS зоне (zetit.local или эквивалент):

brain.zetit.local.    A    <internal-ip>

На внешнем DNS (если используешь публичный контур):

brain.zetit.ru.    A    <external-ip-of-edge-server>

Edge-сервер (где живёт nginx с публичным контуром) проксирует на внутренний IP VM.

Стадия 2: Bootstrap

# Склонируй ZBrain repo
sudo mkdir -p /opt/zbrain && sudo chown $USER:$USER /opt/zbrain
git clone git@git.zetit.ru:zuevav/ZBrain.git /opt/zbrain
cd /opt/zbrain

# Зеркало gbrain (один раз, не на каждой VM)
# Это делается единожды на твоей рабочей машине:
#
#   git clone --mirror https://github.com/garrytan/gbrain.git
#   cd gbrain.git
#   git push --mirror git@git.zetit.ru:zuevav/gbrain-mirror.git

# Запусти bootstrap
sudo TOTAL_RAM_GB=8 FNA_PROXY="http://client_001:PASSWORD@fna.zetit.ru:3128" bash scripts/bootstrap-vm.sh

После завершения скрипт покажет следующие шаги.

Стадия 3: Postgres secrets

sudo -u postgres psql
-- Пароль root postgres юзера (сохрани в KeePass)
ALTER USER postgres PASSWORD 'STRONG_RANDOM_PASSWORD_24_CHARS';

-- Пользователь для brainhub
CREATE USER brainhub WITH PASSWORD 'ANOTHER_STRONG_PASSWORD';
GRANT ALL PRIVILEGES ON DATABASE brainhub TO brainhub;

-- Проверка
\du
\l

\q

Стадия 4: Заполнение .env

sudo cp /etc/zbrain/env.example /etc/zbrain/.env
sudo chmod 600 /etc/zbrain/.env
sudo chown zbrain:zbrain /etc/zbrain/.env
sudo nano /etc/zbrain/.env

Сгенерируй секреты:

# SESSION_SECRET
openssl rand -hex 32

# JWT_SECRET
openssl rand -hex 32

# TOKEN_ENCRYPTION_KEY (для шифрования TOTP секретов)
openssl rand -hex 16

Заполни:

  • DATABASE_URL — с паролем brainhub
  • Секреты выше
  • OPENAI_API_KEY и ANTHROPIC_API_KEY
  • FNA-прокси с реальными credentials
  • INITIAL_OWNER_EMAIL и INITIAL_OWNER_PASSWORD (временный, сменишь после первого логина)

Стадия 5: Первый брейн

sudo bash /opt/zbrain/scripts/create-brain.sh zetit "ZETIT MSP" 3001

Скрипт:

  1. Создаст пользователя gbrain_zetit и БД gbrain_zetit в Postgres
  2. Положит конфиг в /var/lib/zbrain/brains/zetit/
  3. Запустит миграции gbrain
  4. Создаст и запустит systemd unit zbrain-gbrain-zetit

Проверка:

systemctl status zbrain-gbrain-zetit
journalctl -u zbrain-gbrain-zetit -f  # в отдельном окне
curl http://localhost:3001/health

Стадия 6: Импорт первых данных

sudo -u zbrain bash -c '
  export PATH=$HOME/.bun/bin:$PATH
  source /etc/zbrain/.env
  cd /var/lib/zbrain/gbrain
  bun run gbrain import /path/to/your/markdown/files
'

Проверка:

sudo -u postgres psql -d gbrain_zetit -c '
  SELECT
    (SELECT count(*) FROM pages) AS pages,
    (SELECT count(*) FROM content_chunks) AS chunks,
    (SELECT count(*) FROM content_chunks WHERE embedding IS NOT NULL) AS embedded;
'

Стадия 7: Brainhub API + Web

Эта часть требует, чтобы код Sprint 2-5 был написан. До этого пропускаем.

Build

cd /opt/zbrain
sudo -u zbrain bun install
sudo -u zbrain bun run build

Миграции

sudo -u zbrain bun run --cwd apps/api db:migrate

Запуск через docker-compose (рекомендуется в prod)

cd /opt/zbrain/deploy/docker
sudo docker compose up -d
sudo docker compose ps

Альтернатива: systemd

Если не хочешь docker - использовать deploy/systemd/zbrain-brainhub.service.

Стадия 8: Nginx (внутренний контур)

sudo apt-get install -y nginx

# Скопируй конфиг
sudo cp /opt/zbrain/deploy/nginx/zbrain.conf /etc/nginx/sites-available/zbrain

# Закомментируй временно public server-блок (TLS пока нет)

sudo ln -s /etc/nginx/sites-available/zbrain /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default

# Проверь
sudo nginx -t

# Запусти
sudo systemctl reload nginx

Тест:

curl -H "Host: brain.zetit.local" http://localhost/

Стадия 9: TLS для публичного контура

Только если у тебя есть edge-сервер с внешним IP и DNS-запись brain.zetit.ru указывает на него.

На edge-сервере (или на самой VM, если она имеет внешний IP):

sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d brain.zetit.ru

Раскомментируй public server-блок в nginx и перезагрузи.

Стадия 10: Первый логин

  1. Открой http://brain.zetit.local в браузере
  2. Залогинься как INITIAL_OWNER_EMAIL / INITIAL_OWNER_PASSWORD
  3. Сразу смени пароль в Profile
  4. Включи 2FA (когда Sprint 7 готов)
  5. Удали INITIAL_OWNER_* из .env (необязательно, но гигиенично)

Стадия 11: Подключение Claude Code

  1. В UI: создай токен с scope mcp:write:zetit
  2. Скопируй токен
  3. На своей рабочей машине добавь в ~/.claude/mcp.json или в .claude/mcp.json проекта:
{
  "mcpServers": {
    "zbrain-zetit": {
      "transport": "http",
      "url": "http://brain.zetit.local/mcp/zetit",
      "headers": {
        "Authorization": "Bearer brain_pat_<your-token>"
      }
    }
  }
}
  1. Перезапусти Claude Code
  2. Проверь что MCP-инструменты доступны

Стадия 12: Backup

# Создай age ключ для шифрования бэкапов (только один раз!)
age-keygen -o /tmp/backup.age
cat /tmp/backup.age   # сохрани оба ключа в KeePass!

# Положи публичную часть на VM
sudo head -1 /tmp/backup.age | grep public | awk '{print $NF}' > /tmp/pub
sudo mv /tmp/pub /etc/zbrain/backup.age.pub
sudo chmod 644 /etc/zbrain/backup.age.pub

# Удали /tmp/backup.age с VM!
shred -u /tmp/backup.age

# Тест бэкапа
sudo bash /opt/zbrain/scripts/backup.sh

# Добавь в cron
sudo crontab -e
# Добавь строку:
# 0 3 * * *  /opt/zbrain/scripts/backup.sh >> /var/log/zbrain/backup.log 2>&1

Чек-лист готовности

  • VM создана с правильными параметрами
  • Bootstrap отработал без ошибок
  • Postgres работает, пароли установлены
  • .env заполнен и защищён 600
  • Первый брейн создан и работает
  • Данные импортированы
  • Brainhub запущен и доступен через nginx
  • OAuth настроен (если нужно)
  • TLS работает (если публичный контур)
  • Owner логин работает, пароль сменён
  • Claude Code успешно подключается через токен
  • Backup делается и шифруется
  • Восстановление из бэкапа протестировано (на отдельной VM)
  • Мониторинг настроен (опционально)
  • Документация в docs/INFRASTRUCTURE.md обновлена

Типовые проблемы

gbrain не стартует

journalctl -u zbrain-gbrain-zetit -n 50 --no-pager

Частые причины:

  • Пароль в DATABASE_URL не совпадает
  • FNA-прокси недоступен
  • Bun не в PATH (проверь Environment="PATH=..." в unit-файле)

Embeddings не создаются

# Проверь подключение к OpenAI через FNA
sudo -u zbrain bash -c '
  source /etc/zbrain/.env
  curl --proxy "$HTTPS_PROXY" https://api.openai.com/v1/models -H "Authorization: Bearer $OPENAI_API_KEY"
'

Postgres падает

# Проверь логи
sudo tail -100 /var/log/postgresql/postgresql-16-main.log

# Проверь disk space
df -h /var/lib/postgresql/

# Проверь shared_buffers vs RAM
sudo -u postgres psql -c 'SHOW shared_buffers; SHOW effective_cache_size;'

Брейн занимает слишком много места

# Размер по таблицам
sudo -u postgres psql -d gbrain_zetit -c "
SELECT
  schemaname || '.' || tablename AS table,
  pg_size_pretty(pg_total_relation_size(schemaname || '.' || tablename)) AS size
FROM pg_tables
WHERE schemaname = 'public'
ORDER BY pg_total_relation_size(schemaname || '.' || tablename) DESC;
"

Если эмбеддинги занимают слишком много — можно перейти на text-embedding-3-small (вместо large), это даст 1536 → 1024 dim и -33% места.