Установка и первый запуск¶
Пошаговая процедура: от клонирования суперпроекта до работающего ядра платформы
(профили 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-сабмодулями, поэтому клонировать нужно рекурсивно:
Если репозиторий уже склонирован без сабмодулей:
make submodules # git submodule update --init --recursive
make status # указатели сабмодулей и незакоммиченные изменения
Сабмодули встают на ревизии, закреплённые в суперпроекте, — это и есть согласованная версия платформы. Не переключайте их на ветки вручную, если не разрабатываете сам компонент.
Шаг 2. Сгенерировать .env и ключи¶
Что делает цель (Makefile, tools/fill_secrets.py):
- Если
.envнет — копирует.env.exampleв.envи ставит права600. - Заполняет пустые секреты случайными значениями (
secrets.token_hex): пароли всех БД,CP_BOOTSTRAP_TOKEN,IAM_BOOTSTRAP_TOKEN,ENT_BOOTSTRAP_TOKEN,POL_BOOTSTRAP_TOKEN,MEMORY_API_KEY, пароль и секрет клиента Keycloak, ключи MinIO. Уже заданные значения не трогает — повторный запуск безопасен. - Создаёт каталог
secrets/. - Генерирует 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 контейнеров:
Шаг 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.
Проверить состояние:
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 запускает 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¶
-
Впишите tenant IAM в
.env(до bootstrap переменная пуста): -
Перезапустите процессы ядра, чтобы они подхватили service account (
secrets/control-plane-iam.env) — после этого Control Plane ходит в память токеном IAM, а не статическим ключом:
Имя файла состояния — deploy/state/<COMPOSE_PROJECT_NAME>.json (по умолчанию
taimen.json) или значение --name.
Шаг 7. 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 из файла не найден):
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:<порт> |
Больше — в Установке и запуске — диагностике.