Skip to content

Установка сервисов ​

Разворачивание prod-стека Unishift Platform из готовых образов. CLI ush скачивает конфигурацию с storage.unishift.ru, сам генерирует все секреты, накатывает миграции и поднимает сервисы.

Требования ​

На сервере должны быть установлены:

КомпонентПроверка
Docker Enginedocker info
Docker Compose v2 (плагин)docker compose version
curlcurl --version (только для bootstrap install.sh)

Пользователь, от которого запускается установка, должен иметь доступ к docker-демону (входить в группу docker либо запускать под root).

Установщик сам проверяет наличие Docker и останавливается с понятной ошибкой, если чего-то не хватает (например: docker is required but was not found in PATH). На чистом VPS Docker ещё не установлен — сначала подготовьте сервер.

Сколько нужно железа

Требования к CPU, RAM и диску под конкретное число пользователей — в разделе Sizing, схемы размещения на одном и нескольких узлах — в референсных архитектурах.

Подготовка чистого VPS ​

Инструкция рассчитана на свежий Linux-сервер (Ubuntu / Debian и аналоги). Нужны права root или sudo.

1. Базовые утилиты ​

curl обычно уже есть. Если нет:

bash
# Debian / Ubuntu
apt-get update
apt-get install -y curl ca-certificates

2. Установка Docker Engine и Compose v2 ​

Официальный скрипт Docker ставит Engine и плагин Compose одной командой:

bash
curl -fsSL https://get.docker.com | sh

Проверка:

bash
docker info
docker compose version

Демон должен отвечать без ошибок. Если docker есть, а docker info жалуется на права — либо работайте под root, либо добавьте пользователя в группу и перелогиньтесь:

bash
usermod -aG docker "$USER"
# затем новый SSH-сеанс / newgrp docker

Альтернатива: пакеты репозитория Docker

Вместо get.docker.com можно поставить пакеты вручную по официальной инструкции для вашего дистрибутива. Нужны как минимум docker-ce, docker-ce-cli, containerd.io и docker-compose-plugin (команда docker compose, не отдельный docker-compose v1).

После проверки Docker переходите к быстрой установке ниже.

Быстрая установка ​

Одна команда ставит CLI ush (если его нет) и разворачивает стек: файлы, секреты, миграции, контейнеры.

bash
curl -fsSL https://storage.unishift.ru/services/prod/install.sh | bash

install.sh — только bootstrap. Дальше стеком управляет ush platform; bash-скрипты в каталог установки не кладутся.

На чистом VPS без Docker команда завершится ошибкой — сначала выполните подготовку сервера.

Если ush уже в PATH:

bash
ush platform install
ush platform install --public-host 203.0.113.10
ush platform install --public-host app.example.com --public-scheme https
ush platform install --dir /srv/unishift

По умолчанию каталог — /opt/unishift. Там остаются docker-compose.yaml, конфиги (postgres/, centrifugo/, searxng/) и сгенерированный .env.

Те же параметры можно передать переменными в bash при bootstrap (не в curl):

bash
curl -fsSL https://storage.unishift.ru/services/prod/install.sh \
  | PUBLIC_HOST=203.0.113.10 bash

curl -fsSL https://storage.unishift.ru/services/prod/install.sh \
  | PUBLIC_HOST=app.example.com PUBLIC_SCHEME=https bash

curl -fsSL https://storage.unishift.ru/services/prod/install.sh \
  | INSTALL_DIR=/srv/unishift bash

После установки публичный адрес меняется так (секреты в .env не трогает):

bash
ush platform update --public-host 203.0.113.10
ush platform update --public-host app.example.com --public-scheme https
Переменная / флагНазначениеПо умолчанию
INSTALL_DIR / --dirКуда установить/opt/unishift
BASE_URL / --base-urlОткуда качать файлы…/services/prod
REGISTRY / --registryРеестр образовleggnom
TAG / --tagТег образовlatest
PUBLIC_HOST / --public-hostПубличный IP/домен (для UI и WebSocket)localhost
PUBLIC_SCHEME / --public-schemehttp или httpshttp
WEB_BASE_URL / --web-base-urlURL веб-клиентаиз PUBLIC_* (см. ниже)
CENTRIFUGO_WS_URL / --centrifugo-ws-urlWebSocket URL для браузераиз PUBLIC_* (см. ниже)
CENTRIFUGO_ALLOWED_ORIGINS / --centrifugo-allowed-originsOrigin фронтенда (через пробел)из PUBLIC_* (см. ниже)

Как собираются URL, если их не задали явно:

PUBLIC_SCHEMEWEB_BASE_URLCENTRIFUGO_WS_URL
http (по умолчанию)http://HOST:18080ws://HOST:18100/connection/websocket
httpshttps://HOSTwss://HOST/connection/websocket

Для https установщик предполагает reverse proxy на 443 (UI и Centrifugo на одном хосте). Если порты другие — задайте WEB_BASE_URL, CENTRIFUGO_WS_URL и CENTRIFUGO_ALLOWED_ORIGINS явно.

Что разворачивается ​

Полный набор модулей платформы плюс инфраструктура. Мониторинг (Prometheus и экспортеры) в prod не входит — он есть только в dev-стеке (devops/dev).

Модули (25): client, concierge_web, gateway, auth, spaces, documents, task-tracker, notifications, messaging, collatio, concierge, mcp-gateway, command-manager, scheduler, storage, env-manager, flow-manager, spark-grid, ai-router, guard, notebooks, content-extract, nats-bridge, proxy-manager, voice — 23 Go-сервиса и два веб-фронта.

Data Tables, Dashboards и Data Catalog пока не входят в prod-каталог services.yaml (работают в dev-стеке devops/dev).

Инфраструктура: postgres, nats, minio (+ однократный job minio-init), centrifugo, searxng.

Инференс LLM в стек не входит: адрес и имя модели задаёт провайдер в AI Router — см. Локальные модели.

Стек запускается под именем проекта unishift-prod — сеть, тома и контейнеры изолированы от других окружений на той же машине.

Секреты ​

Установщик генерирует их однократно и складывает в INSTALL_DIR/.env с правами 600. Повторный запуск установщика их не трогает.

СекретНазначение
DB_PASSWORDПароль PostgreSQL
JWT_SECRETПодпись JWT и токенов Centrifugo
SESSION_SECRETПодпись сессий
ENCRYPTION_KEYКлюч шифрования Env Manager и SMTP-паролей Notifications (base64 от 32 байт)
SERVICE_TOKENМежсервисные вызовы
CENTRIFUGO_API_KEYСерверный HTTP API Centrifugo
SEARXNG_SECRETСекрет SearXNG
MINIO_ROOT_PASSWORDПароль MinIO

Сделайте резервную копию .env

Потеря ENCRYPTION_KEY делает нечитаемыми все значения, сохранённые в Env Manager. Смена DB_PASSWORD на уже инициализированной БД ломает доступ к данным. Скопируйте INSTALL_DIR/.env в надёжное место после установки.

Порты ​

Публикуются в диапазоне 1xxxx, чтобы не конфликтовать с другими окружениями.

СервисПорт хостаEnv
Веб-клиент (unishift_client_web)18080CLIENT_PORT
Concierge SPA (unishift_concierge_web)18081CONCIERGE_WEB_PORT
Gateway18090GATEWAY_PORT
Auth18091AUTH_PORT
Spaces18092SPACES_PORT
Documents18093DOCUMENTS_PORT
Command Manager18094COMMAND_MANAGER_PORT
Scheduler18095SCHEDULER_PORT
Storage18096STORAGE_PORT
Env Manager18097ENV_MANAGER_PORT
Flow Manager18099FLOW_MANAGER_PORT
Centrifugo18100CENTRIFUGO_PORT
AI Router18101AI_ROUTER_PORT
Task Tracker18102TASK_TRACKER_PORT
Notifications18103NOTIFICATIONS_PORT
MCP Gateway18104MCP_GATEWAY_PORT
Data Tables18105DATA_TABLES_PORT
Concierge API18106CONCIERGE_PORT
Messaging18107MESSAGING_PORT
Collatio18108COLLATIO_PORT
Guard18110GUARD_PORT
Notebooks18111NOTEBOOKS_PORT
Content Extract18112CONTENT_EXTRACT_PORT
Proxy Manager (API / forward proxy)18114 / 18115PROXY_MANAGER_PORT / FORWARD_PROXY_PORT
Voice18116VOICE_PORT
SearXNG18088SEARXNG_PORT
Spark Grid18087SPARK_GRID_PORT
PostgreSQL15432POSTGRES_PORT
NATS (клиент / мониторинг)14222 / 18222NATS_PORT / NATS_MONITOR_PORT
MinIO (API / консоль)19010 / 19011MINIO_PORT / MINIO_CONSOLE_PORT

Имя env порта веб-клиента — CLIENT_PORT (не CLIENT_WEB): образ называется unishift_client_web, переменная хост-порта — CLIENT_PORT.

Строка Data Tables (18105) — зарезервированная переменная .env: сервис пока не входит в prod-каталог, порт не занимается.

Guard NER sidecar в prod-стек не входит и наружу не публикуется: внутри docker-сети слушает 8111 (как и Notebooks, но это разные контейнеры — конфликта нет). При ручном запуске за пределами compose опубликуйте любой свободный хост-порт.

WebSocket и удалённый доступ

Браузер подключается к Centrifugo напрямую по адресу из CENTRIFUGO_WS_URL (gateway отдаёт его в /api/v1/services). Значение ws://localhost:18100/... работает только если UI открыт на той же машине, где крутится стек.

Если в консоли браузера:

text
WebSocket connection to 'ws://localhost:18100/connection/websocket' failed

поправьте публичный адрес и пересоздайте стек:

bash
ush platform update --public-host 203.0.113.10

Порт 18100 должен быть открыт на firewall (или Centrifugo должен быть за reverse proxy с wss://). CENTRIFUGO_ALLOWED_ORIGINS обязан совпадать с Origin страницы (схема + хост + порт UI).

Отдельно: интерактивный терминал и ush connect идут через wss://HOST/proxy/command-manager/... (не Centrifugo). На reverse proxy для location / (или /proxy/) нужны proxy_http_version 1.1, Upgrade/Connection и длинный proxy_read_timeout — иначе handshake даёт 400 Bad Request, а UI пишет «Агент не в сети». Пример — reference-architecture.md.

Логирование ​

В prod по умолчанию LOG_LEVEL=error и LOG_FORMAT=text — в логи попадают только ошибки, обычным текстом (не JSON). Для отладки поднимите уровень в .env:

env
LOG_LEVEL=info    # debug | info | warn | error | fatal | panic
LOG_FORMAT=json   # text | json

Управление ​

Каталог по умолчанию — /opt/unishift (--dir, если другой):

bash
ush platform update                         # файлы со storage + migrate + up -d
ush platform update --public-host <IP>
ush platform upgrade                        # обновить образы установленных сервисов
ush platform services                       # таблица: направление, статус, образ
ush platform ps                             # статус сервисов
ush platform logs -f                        # логи в реальном времени
ush platform logs -f auth                   # логи одного сервиса
ush platform config show                    # .env с маскированными секретами
ush platform enable guard                     # включить сервис (+ зависимости)
ush platform down                           # остановить стек (тома сохраняются)
ush platform up                             # поднять снова
ush platform migrate                        # только миграции и бакет MinIO
ush platform doctor                         # самодиагностика: Docker, порты, секреты, БД
ush platform backup                         # полный бэкап Postgres, MinIO и .env
ush platform restore <archive> --yes        # восстановление из бэкапа

Справка по флагам: ush platform --help и CLI.

Резервное копирование и восстановление ​

Для создания снимка баз данных и хранилища перед обновлениями или переносом:

bash
ush platform backup                         # сохранит в unishift-backup-<timestamp>.tar.gz

Для переноса сервера или отката данных:

bash
ush platform restore unishift-backup-*.tar.gz --yes

Подробно о флагах и составе архива — в документации CLI, а пошаговый перенос описан в SERVER_MIGRATION.md.

Самодиагностика стека (doctor) ​

Самые частые причины сбоя ush platform install — неработающий Docker daemon, конфликты портов с уже запущенными сервисами на сервере, повреждённый .env с пустыми секретами или сбои инициализации базы данных.

Инструмент самодиагностики проверяет все эти точки:

bash
ush platform doctor

Что проверяется:

  • Docker: бинарник docker, плагин docker compose v2 и права/доступ к демону.
  • Хостовые порты: проверяет все 28 стандартных портов платформы — по одной переменной на сервис в .env (включая NATS_MONITOR_PORT и MINIO_CONSOLE_PORT; DATA_TABLES_PORT зарезервирован). Если порт уже занят сторонним процессом (nginx, системный postgres и т.д.), команда выведет точное имя порта и переменной. Если порт занят контейнером текущего стека Unishift — статус помечается как валидный (PASS).
  • Секреты: при наличии .env проверяется непустота всех 8 обязательных сгенерированных секретов (DB_PASSWORD, JWT_SECRET, SESSION_SECRET, ENCRYPTION_KEY, SERVICE_TOKEN, CENTRIFUGO_API_KEY, SEARXNG_SECRET, MINIO_ROOT_PASSWORD) и фиксируется дрифт остальных ключей.
  • БД и контейнеры: проверяется health-статус postgres и minio, а также отсутствие упавших/завершившихся с ошибкой сервисов.

ush platform install выполняет проверку Docker и портов автоматически в режиме preflight перед началом скачивания образов и конфигов.

Локальные модели ​

Prod-стек не содержит Ollama и llama.cpp. Адрес и имя модели задаёт только провайдер: Настройки → AI Router → Провайдеры моделей (/settings/ai-router/providers).

Готовые GGUF: storage.unishift.ru/models.

ФайлИмя моделиCapability
littlelamb-planner.gguflittlelamb-plannerplanner
littlelamb-diagram.gguflittlelamb-diagramdiagram
littlelamb-fill.gguflittlelamb-fillfill
littlelamb.gguf—исходный чекпоинт, в runtime не импортируется

Скачайте файл на машину, где уже запущена Ollama, и импортируйте его там. Платформа этот процесс не поднимает.

bash
curl -fL -o littlelamb-planner.gguf \
  https://storage.unishift.ru/models/littlelamb-planner.gguf
printf 'FROM %s\n' "$PWD/littlelamb-planner.gguf" > Modelfile
ollama create littlelamb-planner -f Modelfile
ollama list

То же для littlelamb-diagram.gguf и littlelamb-fill.gguf: имя модели совпадает с именем файла без .gguf.

Провайдер на каждую capability: vendor ollama, ключ пустой, base URL — адрес этой Ollama (нативный API, без суффикса /v1), поле модели — имя из ollama list. Чат — отдельная запись с capability chat и тем же base URL.

Если base URL в приватной сети, для vendor ollama это допустимо. Для vendor openai на тот же адрес нужен ALLOW_PRIVATE_PROVIDER_URLS=true (в prod-compose уже включено) и base URL с суффиксом /v1.

Decision в этом каталоге нет. Если readout нужен, llama.cpp запускается отдельно от стека. Провайдер: capability decision, vendor llamacpp, base URL этого сервера, ключ пустой. Если в GGUF decision-токены помечены как CONTROL, перед запуском их патчит runtime/models/patch_gguf.py: меняются только метаданные 256 токенов, веса не трогаются, повторный запуск безопасен.

Уже установленный стек без ush ​

На инсталляциях, где в /opt/unishift лежат update.sh / migrate.sh:

bash
curl -fsSL https://storage.unishift.ru/cli/install.sh | bash
ush platform update --public-host <IP>

Старые скрипты в каталоге можно удалить — CLI их не вызывает.

Обновление ​

bash
ush platform update

Команда скачивает актуальные docker-compose.yaml и конфиги, накатывает миграции и делает docker compose up -d. Образы сервисов помечены тегом latest и pull_policy: always — up подтягивает свежую сборку. Инфраструктура (postgres, nats, minio, centrifugo) закреплена на конкретных версиях и не перекачивается.

Закрепить версию ​

Чтобы зафиксировать конкретную версию сервисов вместо latest, задайте TAG в .env и перезапустите:

env
TAG=0.0.3
bash
ush platform up

Миграции ​

Установщик накатывает их автоматически. Запустить вручную (например, после обновления образов с новыми миграциями):

bash
ush platform migrate

Команда поднимает postgres и minio, создаёт бакет и по очереди прогоняет миграции 19 сервисов с БД (auth, spaces, documents, command-manager, scheduler, storage, env-manager, flow-manager, spark-grid, ai-router, task-tracker, notifications, mcp-gateway, messaging, collatio, concierge, guard, notebooks, proxy-manager). Каждый прогон идёт через одноразовый контейнер и убирается за собой.

Переустановка с нуля ​

Тома с данными переживают down. Чтобы удалить и данные тоже:

bash
ush platform down --volumes     # СНОСИТ тома: БД, файлы MinIO, данные NATS

После этого при следующем up PostgreSQL заново отработает init-скрипты и создаст пустые базы — понадобится повторный ush platform migrate.

Если миграции падают с postgres is unhealthy ​

Сначала выполните самодиагностику:

bash
ush platform doctor

Команда покажет текущий статус здоровья postgres и minio и зафиксирует упавшие сервисы.

Permission denied на /docker-entrypoint-initdb.d ​

В логах postgres:

text
ls: cannot open directory '/docker-entrypoint-initdb.d/': Permission denied

и статус Restarting (2). На VPS с umask 077 каталог postgres/init создаётся как 700 root:root, а процесс внутри контейнера идёт под uid 999 и не может его прочитать.

bash
chmod -R a+rX /opt/unishift/postgres /opt/unishift/centrifugo /opt/unishift/searxng
ush platform down --volumes
ush platform migrate
ush platform up

Healthcheck не успевает при первом старте ​

Postgres при холодном старте создаёт десяток баз (init-скрипты). Если healthcheck слишком короткий, контейнер помечается unhealthy, и *-migrate падают с dependency failed to start.

Диагностика:

bash
ush platform ps
ush platform logs --tail 80 postgres
docker inspect "$(cd /opt/unishift && docker compose ps -q postgres)" --format '{{json .State.Health}}'

Восстановление (.env с секретами сохраняется, сносятся только тома):

bash
ush platform down --volumes
ush platform update