Перейти к содержанию

Установка и первый запуск

Пошаговая процедура: от клонирования суперпроекта до работающего ядра платформы (профили core edge), прошедшего bootstrap и smoke-проверку. Рассчитана на локальную машину или тестовый сервер; для промышленного стенда шаги те же, но .env и Caddyfile другие — см. Промышленное развёртывание.

Что получится в конце

  • 9 контейнеров профилей core и edge в состоянии running/healthy;
  • tenant, оператор-человек с правами администратора, проект и workspace;
  • PAT оператора в secrets/harness-pat и service account ядра в secrets/control-plane-iam.env;
  • каталог по файлу установки deploy/packages.yaml (ядро без пакетов знает только системный тип задачи task).

Шаг 0. Проверить требования

Убедитесь, что установлены Docker с Compose v2.24+, git, make, Python 3 с uv (без него — PyYAML и jsonschema в системном Python), openssl, и свободны порты 80, 18000, 18001, 18010. Подробно — Требования.

Шаг 1. Получить исходники

Компоненты подключены git-сабмодулями, поэтому клонировать нужно рекурсивно:

git clone --recurse-submodules <url-суперпроекта> taimen
cd taimen

Если репозиторий уже склонирован без сабмодулей:

make submodules          # git submodule update --init --recursive
make status              # указатели сабмодулей и незакоммиченные изменения

Сабмодули встают на ревизии, закреплённые в суперпроекте, — это и есть согласованная версия платформы. Не переключайте их на ветки вручную, если не разрабатываете сам компонент.

Шаг 2. Сгенерировать .env и ключи

make secrets

Что делает цель (Makefile, tools/fill_secrets.py):

  1. Если .env нет — копирует .env.example в .env и ставит права 600.
  2. Заполняет пустые секреты случайными значениями (secrets.token_hex): пароли всех БД, CP_BOOTSTRAP_TOKEN, IAM_BOOTSTRAP_TOKEN, ENT_BOOTSTRAP_TOKEN, POL_BOOTSTRAP_TOKEN, MEMORY_API_KEY, пароль и секрет клиента Keycloak, ключи MinIO. Уже заданные значения не трогает — повторный запуск безопасен.
  3. Создаёт каталог secrets/.
  4. Генерирует RSA-3072 ключи подписи secrets/iam-signing.pem и secrets/entitlement-signing.pem (если их нет) и ставит им 600.
создан .env
заполнены секреты: CP_POSTGRES_PASSWORD, IAM_POSTGRES_PASSWORD, …, S3_SECRET_ACCESS_KEY
секреты на месте: .env, secrets/*.pem (на Linux: chown 10001 secrets/*.pem)

На Linux сразу отдайте ключи uid контейнеров:

sudo chown 10001:10001 secrets/*.pem

Шаг 3. Проверить .env перед первым запуском

Для ядра (core edge) правки .env после make secrets не нужны.

Переменные опциональных профилей

IAM_TENANT_ID, SUPPORT_WORKSPACE_ID и SUPPORT_BOT_PAT после make secrets остаются пустыми — сгенерировать их нечем. В compose.yml они по умолчанию пусты, поэтому make up для ядра работает без них. IAM_TENANT_ID впишите после bootstrap (шаг 6). Остальные две нужны только профилю demo: без них демо бота поддержки работает без Control Plane.

Шаг policy в bootstrap

make secrets заполняет POL_BOOTSTRAP_TOKEN, но трогать его не нужно: если профиль policy не поднят, bootstrap пропускает шаг 7 с сообщением и завершается успешно. Сделать профиль обязательным можно флагом --policy — см. Bootstrap.

Необязательно: LLM-провайдер

Память по умолчанию работает офлайн (MEMORY_EMBEDDING_PROVIDER=fake, MEMORY_LLM_PROVIDER=echo): поиск работает, но эмбеддинги фиктивные. Для настоящего поиска укажите OpenAI-совместимый endpoint — см. Конфигурацию .env.

Шаг 4. Поднять ядро

make config       # проверить compose.yml после интерполяции
make up           # docker compose --profile core --profile edge up -d --build

Первая сборка занимает несколько минут. Порядок старта задан depends_on с healthcheck: базы → iam-service и memory-service → control-plane-api (применяет миграции Alembic) → control-plane-worker и context-adapter.

Проверить состояние:

make ps
NAME                           SERVICE                STATUS
taimen-caddy-1                 caddy                  Up
taimen-context-adapter-1       context-adapter        Up
taimen-control-plane-api-1     control-plane-api      Up (healthy)
taimen-control-plane-db-1      control-plane-db       Up (healthy)
taimen-control-plane-worker-1  control-plane-worker   Up
taimen-iam-db-1                iam-db                 Up (healthy)
taimen-iam-service-1           iam-service            Up (healthy)
taimen-memory-db-1             memory-db              Up (healthy)
taimen-memory-service-1        memory-service         Up (healthy)

Логи отдельного сервиса: make logs svc=control-plane-api.

Шаг 5. Выполнить bootstrap

Bootstrap создаёт tenant, оператора, его PAT, проект, workspace, каталог типов задач и service accounts. Скрипт идемпотентен: повторный запуск пропускает сделанное.

make bootstrap ARGS='--operator "Alice Operator"'

make bootstrap запускает deploy/bootstrap.py через uv run --no-project --with pyyaml --with jsonschema python3, если uv установлен, иначе — системным python3 (тогда PyYAML и jsonschema нужны в нём).

--operator — отображаемое имя первого человека-администратора; задайте своё. Ожидаемый вывод (идентификаторы сокращены):

1. ожидание сервисов
2. IAM tenant, audience, principal оператора
   IAM tenant <tenant-id> оператор <iam-principal-id>
   !! впишите в .env: IAM_TENANT_ID=<tenant-id> (нужен platform-api)
2a. service account Control Plane в IAM
   выпущен → secrets/control-plane-iam.env client <client-id>
   !! перезапустите ядро, чтобы оно взяло env-файл: docker compose up -d control-plane-api control-plane-worker context-adapter
3. Control Plane bootstrap с binding оператора
   tenant <tenant-id> оператор <cp-principal-id> binding <binding-id>
   единый tenant: platform-core сидировать с SEED_TENANT_ID=<tenant-id>
4. PAT оператора
   выпущен → secrets/harness-pat prefix <prefix>
   обмен PAT → access token: ok
5. Control Plane: project template, workspace, legacy-ключ
   project <project-id> workspace <workspace-id>
5b. Каталог из пакетов: deploy/packages.yaml (TAI-ADR-0044)
   пакеты: core 0.1.0
   …
5c. notification-service: service account IAM по описанию, личность в ядре, env-файл
   выпущен → secrets/notification-iam.env client <client-id>
   !! перезапустите сервис: docker compose --profile notify up -d notification-service
   ревизия 1 principal <principal-id>
5d. fleet-controller: service account IAM по описанию, личность в ядре, env-файл
   …
   legacy admin api-key отозван
готово: deploy/state/taimen.json
credential для MCP-плагина/CLI: ~/.config/iam/credentials.json, ключ http://taimen.localhost/iam|<tenant-id>|<iam-principal-id> → содержимое secrets/harness-pat

Что происходит на каждом шаге — в статье Bootstrap.

Шаг 6. Применить результаты bootstrap

  1. Впишите tenant IAM в .env (до bootstrap переменная пуста):

    TENANT=$(python3 -c 'import json;print(json.load(open("deploy/state/taimen.json"))["iamTenantId"])')
    sed -i.bak -E "s/^IAM_TENANT_ID=.*/IAM_TENANT_ID=$TENANT/" .env
    
  2. Перезапустите процессы ядра, чтобы они подхватили service account (secrets/control-plane-iam.env) — после этого Control Plane ходит в память токеном IAM, а не статическим ключом:

    docker compose up -d control-plane-api control-plane-worker context-adapter
    

Имя файла состояния — deploy/state/<COMPOSE_PROJECT_NAME>.json (по умолчанию taimen.json) или значение --name.

Шаг 7. Smoke-проверка

make smoke
  iam-service          OK  200 http://127.0.0.1:18010/healthz
  control-plane-api    OK  200 http://127.0.0.1:18000/health/ready
  memory-service       OK  200 http://127.0.0.1:18001/healthz
  entitlement-service  —   не запущен
  platform-api         —   не запущен
  keycloak             —   не запущен
  platform-web         —   не запущен
  support-bot          —   не запущен

tools/smoke.py проверяет healthz только запущенных сервисов (не поднятые помечаются «не запущен» и ошибкой не считаются) и возвращает ненулевой код, если хоть один запущенный ответил ошибкой.

Шаг 8. Проверить вход оператора

Обменяйте PAT оператора на токен Control Plane и спросите, кто вы:

PAT=$(cat secrets/harness-pat)
TOKEN=$(curl -s -X POST http://127.0.0.1:18010/api/v1/platform-access-tokens:exchange \
  -H 'Content-Type: application/json' \
  -d "{\"token\": \"$PAT\", \"audience\": \"control-plane\"}" | jq -r .accessToken)

curl -s http://127.0.0.1:18000/api/v1/harness/context \
  -H "Authorization: Bearer $TOKEN" | jq '{tenant, principal, permissions}'
{
  "tenant": { "id": "<tenant-id>", "slug": "taimen", "name": "Taimen" },
  "principal": { "id": "<principal-id>", "kind": "human", "displayName": "Alice Operator" },
  "permissions": ["admin", "approvals.decide", "tasks.claim", "…"]
}

Интерактивная документация API Control Plane доступна по http://taimen.localhost/docs (через Caddy) или http://127.0.0.1:18000/docs.

Дальше — Первая задача.

Остановка и сброс

Действие Команда Данные
Остановить make down сохраняются в volumes
Поднять снова make up те же данные; bootstrap повторять не нужно
Пересобрать один сервис docker compose build control-plane-api && docker compose up -d control-plane-api control-plane-worker context-adapter сохраняются
Полный сброс см. ниже удаляются

Полный сброс стенда

Удаление volumes уничтожает все задачи, identity и знания. После него обязательно уберите и состояние bootstrap — иначе скрипт остановится на проверке state (IAM tenant из файла не найден):

docker compose --profile "*" down -v
make reset-state
make up && make bootstrap

make reset-state переносит deploy/state/<имя>.json и выданные bootstrap credentials в secrets/stale-<время>/; .env и ключи подписи остаются на месте.

Типичные проблемы

Симптом Причина Что сделать
required variable … is missing a value при make up пусты секреты, которые генерирует make secrets make secrets
set CP_POSTGRES_PASSWORD и подобные не выполнен make secrets или .env не в корне make secrets
iam-service рестартует, в логах PermissionError на ключ подписи Linux, файл ключа принадлежит root sudo chown 10001:10001 secrets/*.pem
bootstrap: нужен PyYAML / нужен jsonschema uv не установлен, у системного Python нет зависимостей установить uv (make bootstrap возьмёт их сам) или pip install pyyaml jsonschema
bootstrap: не дождался http://127.0.0.1:18040/healthz запуск с --policy, профиль policy не поднят поднять профиль policy или запускать без --policy — шаг 7 пропустится
bootstrap: … ссылается на IAM tenant …, которого нет в IAM (volumes сброшены?) volumes сброшены, а deploy/state/<имя>.json остался make reset-state и повторить bootstrap
bootstrap: HTTP 409 … already_bootstrapped на шаге 3 Control Plane уже инициализирован, а файла состояния нет восстановить deploy/state/<имя>.json или сделать полный сброс
bind: address already in use на 80 порт занят другим веб-сервером освободить порт или поднимать без edge (make up PROFILES=core) и работать через 127.0.0.1
curl: Could not resolve host: taimen.localhost системный резолвер не знает *.localhost строка в /etc/hosts или адреса 127.0.0.1:<порт>

Больше — в Установке и запуске — диагностике.

См. также