Skip to content

Референсные архитектуры развёртывания ​

Готовые схемы размещения Unishift Platform: от одной виртуалки для пилота до закрытого контура с локальным инференсом и распределённым продуктивом. Числа по железу — в Sizing, требования к ОС и порядок установки — в Установке сервисов.

Слои и точки входа ​

                 браузер / CLI / внешние клиенты
                              │
                    ┌─────────┴──────────┐
                    │  reverse proxy TLS │  nginx / Traefik :443
                    └─────────┬──────────┘
              ┌───────────────┼────────────────┬───────────────┐
              ▼               ▼                ▼               ▼
        client :18080   centrifugo :18100  gateway :18090  concierge_web :18081
        (SPA + /api,/proxy)  (WebSocket)     (REST API)     (портал партнёров)
              │               │                │
              └────── docker network: unishift ─┘
                              │
      ┌───────────────────────┼────────────────────────┐
      ▼                       ▼                        ▼
  25 Go-сервисов        инфраструктура            AI-инференс
  gateway, auth,        postgres, nats,           ollama, llama-decision,
  spaces, documents,    minio, centrifugo,        voice
  ai-router, guard …    searxng

В прод-compose наружу (на 0.0.0.0) публикуются только четыре порта:

ПортСервисЗачемКому открывать
18080client (nginx)SPA и прокси /api/, /proxy/ на gatewayвсем пользователям
18100centrifugoWebSocket realtime, браузер подключается напрямуювсем пользователям
18090gatewayREST API для CLI ush connect, unishift-client-go/py, интеграцийпо необходимости, лучше по allowlist
18081concierge_webвнешний портал поддержки партнёровпартнёрам, если модуль используется

Остальные порты (Postgres 15432, NATS 14222, MinIO 19010/19011, Ollama 18084, llama-decision 18088, SearXNG 18088, все сервисы 1809x–18116) привязаны к 127.0.0.1 — доступны только с самого узла для отладки и CLI. В интернет их выставлять не нужно.

Конфликт портов 18088

SearXNG и llama-decision по умолчанию оба занимают 18088. Если включаете профиль decision, задайте DECISION_PORT (например, 18089) в .env.

Вариант A. Пилот и демо ​

Одна виртуальная машина, AI — через внешний API-провайдер.

┌──────────────────────────────────────────────────────────┐
│ VM: 4 vCPU / 8 ГБ RAM / 100 ГБ SSD                       │
│                                                          │
│  reverse proxy (self-signed или Let's Encrypt)           │
│  ├── client :18080 ── centrifugo :18100                  │
│  └── gateway :18090 (опционально)                        │
│                                                          │
│  core + business + ai-router, guard, content-extract     │
│  postgres / nats / minio / centrifugo / searxng           │
│                                                          │
│  egress: proxy-manager → внешний LLM API                 │
└──────────────────────────────────────────────────────────┘
  • Профиль установки: core + business + выборочно из automate (ai-router, guard, content-extract, notebooks).
  • ollama, voice, llama-decision не нужны — AI идёт через API провайдера, egress закрывается через proxy-manager.
  • Внешний контур допустим только если политика компании разрешает отправку данных провайдеру; иначе переходите к варианту C.
  • Аудитория: до 25 пользователей, демонстрации, разработка, приёмка.
  • Не подходит для прода: нет бэкапов, нет TLS-периметра по умолчанию, один узел.

Вариант B. Продуктив на 200 пользователей ​

Один app-узел с полным стеком и отдельный узел (или NAS) для резервных копий. Рекомендуемая типовая схема.

┌───────────────────────────────────────────────┐   ┌──────────────────────┐
│ APP-УЗЕЛ: 16 vCPU / 32 ГБ / 1 ТБ NVMe         │   │ БЭКАП-УЗЕЛ: 2 ТБ     │
│                                               │   │  ┌────────────────┐  │
│  nginx/Traefik :443 ── TLS, HSTS, WS upgrade  │──▶│  │ pg_dump (daily)│  │
│    ├── /            → client :18080           │   │  │ minio mirror   │  │
│    ├── /ws          → centrifugo :18100       │   │  │ .env + compose │  │
│    └── /api,/proxy  → client → gateway        │   │  └────────────────┘  │
│                                               │   └──────────────────────┘
│  полный стек: 34 сервиса + 20 миграций        │
│  postgres-data  nats-data  minio-data         │
│  searxng-data   ollama-data voice-models      │
│                                               │   ┌──────────────────────┐
│  AI: служебные модели на CPU (littlelamb ×3,  │   │ Мониторинг (опция)   │
│      bosun 0.6B, nomic-embed) + внешний API   │──▶│ Prometheus + Grafana │
│      для чата, либо локальный чат на GPU      │   │ Loki/Graylog, алерты │
└───────────────────────────────────────────────┘   └──────────────────────┘
  • Дисковые разделы: система 60 ГБ + данные 1 ТБ NVMe (/var/lib/docker).
  • Разделяйте тома: postgres-data и minio-data на быстром диске, кэш SearXNG — можно на медленном.
  • TLS обязателен: сессионная кука и JWT ходят через периметр.
  • AI: гибрид — служебные модели локально (планировщик, диаграммы, decision, эмбеддинги), чат — внешний API либо GPU-узел (см. вариант C).
  • Бэкап на отдельный узел обязателен: платформа не делает его автоматически.

Конфигурация периметра (пример nginx):

nginx
server {
    listen 443 ssl http2;
    server_name unishift.example.com;

    ssl_certificate     /etc/ssl/unishift/fullchain.pem;
    ssl_certificate_key /etc/ssl/unishift/privkey.pem;

    client_max_body_size 1g;   # совпадает с LOCATION_MAX_SIZE у storage

    location / {
        proxy_pass http://127.0.0.1:18080;
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 300s;           # длинные AI-ответы
    }

    location /connection/websocket {       # Centrifugo
        proxy_pass http://127.0.0.1:18100;
        proxy_http_version 1.1;
        proxy_set_header Upgrade    $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 3600s;
    }
}

Домен, WebSocket и CORS

За reverse proxy задайте в .env:

  • CENTRIFUGO_WS_URL=wss://unishift.example.com/connection/websocket — клиент берёт адрес WebSocket из discovery gateway; с localhost из браузера пользователя подключения не будет;
  • CENTRIFUGO_CLIENT_ALLOWED_ORIGINS=https://unishift.example.com — иначе Centrifugo отклонит подключение по Origin;
  • WEB_BASE_URL и CONCIERGE_WEB_URL — публичные адреса, а не localhost.

Вариант C. Закрытый контур с локальным инференсом ​

Air-gap: ни данных, ни моделей извне. Инференс вынесен на отдельный узел с GPU.

┌──────────────────────────────────────────┐   ┌───────────────────────────────┐
│ APP-УЗЕЛ (закрытая сеть)                 │   │ AI-УЗЕЛ                       │
│ 16 vCPU / 32 ГБ / 1 ТБ NVMe              │   │ 16 vCPU / 64 ГБ / 500 ГБ NVMe │
│                                          │   │ GPU 24 ГБ VRAM                │
│  полный стек, включая voice              │   │                               │
│  guard (DLP) + guard-ner (при включении) │──▶│ ollama   :11434               │
│  searxng: выключен или внутренний поиск  │   │ llama-decision :8080          │
│  egress: только внутренние адреса        │   │ voice (STT/TTS) при нагрузке  │
└──────────────────────────────────────────┘   └───────────────────────────────┘
        ▲
        │ offline-доставка: внутренний registry / tar-архивы образов,
        │ GGUF-модели и voice-модели — файлами

Что важно в этом варианте:

  • Установка без интернета. ush platform install/update тянет образы из registry; для air-gap поднимите внутренний registry (Harbor/Nexus) или готовьте tar-архивы docker save/load и указывайте REGISTRY + TAG в .env. Публичный install.sh в закрытом контуре не используется.
  • Доставка моделей. ollama умеет брать набор из манифеста: OLLAMA_MODELS_MANIFEST_URL или OLLAMA_MODELS можно направить на внутренний файловый сервер (OLLAMA_MODEL_BASE_URL), без пересборки образа.
  • Decision-модель. llama-decision не скачивает модели сам: GGUF кладётся в ./llama-decision/models/ рядом с compose, затем обязательно прогоняется patch_gguf.py — иначе readout не работает. Каталог вне git, включите его в бэкап конфигов.
  • Voice. Модели TTS/STT лежат в томе voice-models; при переносе узла их нужно доставить отдельно.
  • SearXNG требует внешней сети. В закрытом контуре либо выключайте web_search-инструменты AI Router, либо поднимайте внутренний поисковый шлюз и указывайте его как SEARXNG-совместимый endpoint.
  • DLP. guard работает и без NER-сайдкара; guard-ner в прод-compose не входит — при включении закладывайте CPU/RAM и доставку его образа.

Вариант D. Рост и отказоустойчивость (проектный) ​

Горизонтальное масштабирование и HA платформа «из коробки» не поддерживает: compose описывает один экземпляр каждого сервиса, общий TAG, локальные тома. Схема ниже — предмет отдельного проекта, а не настройки по умолчанию.

                       ┌───────────────────────────┐
                       │ LB / ingress (TLS, WS)    │
                       └─────────────┬─────────────┘
              ┌──────────────────────┼──────────────────────┐
              ▼                      ▼                      ▼
        app-узел 1              app-узел 2              app-узел 3
        gateway, сервисы        gateway, сервисы        gateway, сервисы
   (сервисы stateless; сессия — кука + JWT; Centrifugo масштабируется
    через NATS-broker, который уже настроен в compose)
              │                      │                      │
              └──────────┬───────────┴───────────┬──────────┘
                         ▼                       ▼
              PostgreSQL HA (Patroni)     MinIO distributed (4 узла)
              + WAL-архив и PITR          + erasure coding
                         │
        NATS-кластер (3 узла) ── Centrifugo (N) ── общая ФС для sandbox
        Flow Manager и артефактов раннеров ── пул GPU-узлов инференса

Что придётся доделать помимо железа:

ТемаЧто нужно
Postgresвынести из compose: Patroni/реплика + WAL-архив + PITR, отдельный бэкап-контур
ФайлыMinIO в распределённом режиме; проверить, что endpoint из LOCATION_ENDPOINT доступен клиентам — presigned URL подписывается под этот host
Flow Managersandbox и артефакты пишутся на локальный диск узла → нужна общая ФС (NFS/CSI) либо pinning задач на узел
Сессии и WSсервисы stateless, но WebSocket требует либо sticky, либо JWT-подключения к любому узлу Centrifugo (NATS-broker уже включён)
НаблюдаемостьPrometheus + Grafana + Alertmanager + сбор логов (в dev-стенде есть готовый пример devops/obs-lab с Grafana, Zabbix, Graylog и MCP-доступом для агента devops)
Версииединый TAG на все сервисы — при поэтапном обновлении узлов фиксируйте совместимость версий вручную

Диски, тома и что бэкапить ​

ТомСодержимоеБэкап
postgres-dataвсе БД сервисов, векторный индекс RAGда, обязательно, ежедневно
minio-dataфайлы (документы, медиа, артефакты, аватары)да, обязательно
nats-dataJetStream: события, очередижелательно (иначе теряются необработанные события)
ollama-dataлокальные моделинет, восстанавливается из манифеста
voice-modelsTTS/STT-моделинет, доставляются файлами
searxng-dataкэш поисканет
./llama-decision/modelsGGUF decision-модели + патчда, конфиг-артефакт
.env, docker-compose.yaml, services.yamlсекреты и конфигурация стекада, в защищённое хранилище

Порядок бэкапа: сначала БД (pg_dump/pg_dumpall), затем MinIO. При восстановлении сначала поднимается инфраструктура, затем накатываются миграции (ush platform migrate), затем сервисы. Полный ручной порядок — в devops/prod/SERVER_MIGRATION.md.

Обновление без простоя (насколько возможно) ​

  1. Зафиксировать версию: TAG в .env — обновление меняет все сервисы сразу.
  2. Снять дамп БД и копию конфигов до миграций: pre-migration snapshot платформа не делает автоматически.
  3. ush platform update (есть --check и --rollback) → ush platform migrate → ush platform ps.
  4. Проверить health-эндпоинты и WebSocket. Плановое окно — на время миграций.

Чек-лист приёмки инсталляции ​

  • [ ] ush platform ps — все сервисы running/healthy, миграции без ошибок.
  • [ ] Открывается UI по публичному HTTPS-адресу, вход первым админом выполнен.
  • [ ] WebSocket живой: события приходят без перезагрузки страницы.
  • [ ] Наружу открыты только нужные порты; 1809x–18116 недоступны извне.
  • [ ] TLS-сертификат валиден, CENTRIFUGO_CLIENT_ALLOWED_ORIGINS совпадает с доменом.
  • [ ] Заданы лимиты ресурсов (override) хотя бы для Postgres, ai-router, flow-manager, content-extract, ollama.
  • [ ] Настроен ежедневный бэкап БД и MinIO на отдельный узел, выполнена пробная реставрация на чистом стенде.
  • [ ] AI-провайдеры проверены: чат, эмбеддинги, RAG-поиск, decision-гейты.
  • [ ] Мониторинг: доступны метрики и алерты на недоступность сервисов, заполнение диска, ошибки 5xx.
  • [ ] Пользователи, права и секции настроены; guard включён, если требуется DLP.

Дальше ​