Панель платформы¶
Панель платформы — веб-консоль для людей: вход по 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 невозможен.
Порядок первичной настройки¶
- Поднять ядро и выполнить
make bootstrap; вписатьIAM_TENANT_IDв.env. - Поднять профиль
platformи дождатьсяhealthyуkeycloakиplatform-api. - Зарегистрировать Keycloak как identity provider в IAM (Keycloak → Связь с IAM).
- Создать tenant, организацию и пользователя в базе platform-api и
пользователя в Keycloak с атрибутом
tenant_id(Keycloak → Пользователи). - Завести человеку IAM-principal с привязкой внешней identity и binding в Control Plane (platform-api → Подключение человека).
- Включить 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 — самый тяжёлый компонент панели; на машинах с малым объёмом памяти учитывайте его при планировании (см. Ресурсы и масштабирование).