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

Панель платформы

Панель платформы — веб-консоль для людей: вход по e-mail и паролю через Keycloak, администрирование tenant'а, документы и модули продуктов (консоль Control Plane и модули вертикальных пакетов). Раздел описывает устройство панели, её компоненты и эксплуатацию. Адресован администраторам инсталляции и разработчикам, которые подключают к панели новые сервисы.

Замороженный периметр

Профиль compose platform заморожен (обоснование — TAI-ADR-0034 п.4, TAI-ADR-0039): компоненты работают и исправляются при поломке, но новых функций не получают. По умолчанию (make up) панель не поднимается — только профили core edge. Ядро платформы (Control Plane, IAM, память, runner) от панели не зависит: агенты и операторский харнесс работают без неё.

Из чего состоит панель

Сервис compose Образ Назначение
platform-db postgres:16-alpine две базы в одном кластере: platform (данные platform-api) и keycloak
platform-redis redis:7-alpine счётчики rate limit, кэш, брокер событий платформы
realm-render busybox одноразовый: подставляет секреты в шаблон realm Keycloak перед стартом
keycloak quay.io/keycloak/keycloak:26.5.2 вход людей, realm platform; см. Keycloak
minio minio/minio S3-совместимое хранилище документов и аватаров
minio-bootstrap minio/mc одноразовый: создаёт бакет S3_BUCKET
platform-migrations из platform-core одноразовый: миграции базы platform
platform-api из platform-core/apps/api API панели и шлюз к сервисам; см. platform-api
platform-web из platform-web веб-консоль на Next.js; см. Веб-консоль

Одноразовые контейнеры (realm-render, minio-bootstrap, platform-migrations) завершаются с кодом 0; keycloak и platform-api ждут их успешного завершения (service_completed_successfully).

Как панель встроена в платформу

flowchart LR
    B[Браузер] -->|HTTPS| C[Caddy]
    C -->|"/"| W[platform-web]
    C -->|"/auth/*"| K[Keycloak]
    C -->|"/platform/*"| A[platform-api]
    W -->|"server-side, Bearer Keycloak"| A
    A -->|"federation:exchange"| I[iam-service]
    A -->|"Bearer audience control-plane"| CP[control-plane-api]
    A -->|"Bearer audience пакета"| V[сервис вертикального пакета]
    A --> DB[(platform-db)]
    A --> R[(platform-redis)]
    A --> M[(MinIO)]
    K --> DB

Ключевые свойства схемы:

  • У людей и у агентов разные дороги входа. Агенты и локальный харнесс обменивают Platform Access Token в IAM (см. Токены). Человек в браузере входит в Keycloak, а platform-api меняет его токен Keycloak на токен нужного audience через федерацию IAM (см. Федерация identity).
  • У веб-консоли нет собственных credential к сервисам. Все вызовы Control Plane и вертикальных пакетов идут через шлюз /api/v1/services/{service}/… от имени вошедшего человека.
  • Resource service остаётся точкой принятия решения. Шлюз не фильтрует пути: права проверяет Control Plane (или сервис пакета) по binding'у IAM-principal'а.

Раскладка путей на внешнем контуре

Панель живёт на одном хосте с остальной платформой. Раскладка задаётся Caddyfile (deploy/caddy/Caddyfile.local локально, свой файл в промышленной инсталляции — см. Периметр и TLS).

Путь Куда Префикс срезается
/auth/* keycloak:8080 нет — Keycloak сам живёт под /auth (KC_HTTP_RELATIVE_PATH)
/platform/* platform-api:8000 да; API знает префикс через UVICORN_ROOT_PATH=/platform
/iam/* iam-service:8010 да
/api/v1/*, /health/*, /metrics, /docs*, /openapi.json control-plane-api:8000 нет
всё остальное (/) platform-web:3000 нет

Отсюда публичные адреса (для TAIMEN_PUBLIC_URL=https://platform.example.com):

Что Адрес
Консоль https://platform.example.com/
Issuer realm Keycloak https://platform.example.com/auth/realms/platform
API панели https://platform.example.com/platform/api/v1/…
Шлюз к Control Plane https://platform.example.com/platform/api/v1/services/control-plane/api/v1/…

Hairpin через внешний адрес

platform-api проверяет токены Keycloak и выполняет password grant по публичному адресу (KEYCLOAK_URL=${TAIMEN_PUBLIC_URL}/auth), чтобы iss в токене совпадал с тем, что видит браузер. Поэтому контейнеры должны резолвить публичный хост. Локально это обеспечивает сетевой alias сервиса caddy (TAIMEN_PUBLIC_HOST, по умолчанию taimen.localhost). В промышленной инсталляции публичный DNS-адрес должен быть доступен изнутри docker-сети.

Запуск

Панель поднимается отдельным профилем поверх ядра:

# один раз: .env с секретами (make secrets генерирует пароли и ключи)
make secrets

# ядро + панель + внешний контур
make up PROFILES="core platform edge"
# то же самое напрямую
docker compose --profile core --profile platform --profile edge up -d

Переменные, без которых compose не стартует (:? в compose.yml):

Переменная Назначение
PLATFORM_POSTGRES_PASSWORD пароль роли platform в platform-db
KEYCLOAK_DB_PASSWORD пароль роли keycloak (создаётся init-скриптом при первом запуске тома)
REDIS_PASSWORD пароль Redis
KEYCLOAK_ADMIN_PASSWORD пароль администратора Keycloak (KEYCLOAK_ADMIN, по умолчанию admin)
KEYCLOAK_CLIENT_SECRET секрет confidential-клиента platform-api; подставляется в realm
S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY root-ключи MinIO и ключи доступа platform-api

Для работы шлюза дополнительно нужен IAM_TENANT_ID — id tenant'а IAM, который печатает make bootstrap (см. Bootstrap). Без него шлюз смонтирован, но обмен identity невозможен.

Порядок первичной настройки

  1. Поднять ядро и выполнить make bootstrap; вписать IAM_TENANT_ID в .env.
  2. Поднять профиль platform и дождаться healthy у keycloak и platform-api.
  3. Зарегистрировать Keycloak как identity provider в IAM (Keycloak → Связь с IAM).
  4. Создать tenant, организацию и пользователя в базе platform-api и пользователя в Keycloak с атрибутом tenant_id (Keycloak → Пользователи).
  5. Завести человеку IAM-principal с привязкой внешней identity и binding в Control Plane (platform-api → Подключение человека).
  6. Включить feature flag модуля консоли для tenant'а (Веб-консоль → Видимость модулей).

Проверка работоспособности

# статус контейнеров профиля
docker compose --profile platform ps

# platform-api: liveness и readiness (порт на 127.0.0.1)
curl -s http://127.0.0.1:18080/health
curl -s http://127.0.0.1:18080/ready

# Keycloak: discovery-документ realm через внешний контур
curl -s https://platform.example.com/auth/realms/platform/.well-known/openid-configuration | jq .issuer

Порты на 127.0.0.1 по умолчанию: PLATFORM_API_HOST_PORT=18080, KEYCLOAK_HOST_PORT=18081, PLATFORM_WEB_HOST_PORT=13000. Наружу смотрит только Caddy.

Ресурсы

Лимиты памяти задаются переменными окружения (значения по умолчанию из compose.yml):

Контейнер Переменная По умолчанию
keycloak KEYCLOAK_MEM_LIMIT 768m
platform-api PLATFORM_API_MEM_LIMIT 512m
platform-web PLATFORM_WEB_MEM_LIMIT 512m
minio MINIO_MEM_LIMIT 256m
platform-redis REDIS_MEM_LIMIT 128m
platform-db PG_MEM_LIMIT 256m

Keycloak — самый тяжёлый компонент панели; на машинах с малым объёмом памяти учитывайте его при планировании (см. Ресурсы и масштабирование).

См. также