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

Сервисы и порты

Все сервисы корневого compose.yml: профиль, образ или контекст сборки, внутренний и публикуемый порт, зависимости, volumes, healthcheck, лимит памяти и маршрут во внешнем контуре (Caddy). Статья для инженера, который разворачивает стек, открывает порты на хосте или ищет, какой контейнер отвечает на путь /….

Общая схема

flowchart LR
    B[Браузер / харнесс / агент] -->|80 / 443| CADDY[caddy<br/>edge]
    CADDY -->|/iam/*| IAM[iam-service:8010]
    CADDY -->|/api/v1/*, /health/*, /docs| CP[control-plane-api:8000]
    CADDY -->|/auth/*| KC[keycloak:8080]
    CADDY -->|/platform/*| PAPI[platform-api:8000]
    CADDY -->|/support-demo/*| SB[support-bot:8000]
    CADDY -->|/fleet/*| FC[fleet-controller:8040]
    CADDY -->|/memory/* только локально| MEM[memory-service:8077]
    CADDY -->|/ остальное| WEB[platform-web:3000]
    CP --> MEM
    CP --> IAM
    CA[context-adapter] --> MEM
  • Все контейнеры в одной сети taimen (имя — ${TAIMEN_NETWORK:-taimen_default}) и обращаются друг к другу по DNS-именам сервисов.
  • Наружу смотрит только caddy. Остальные сервисы публикуют порт исключительно на 127.0.0.1 — для make smoke, make bootstrap и отладки с хоста.
  • У контейнера caddy есть сетевой alias ${TAIMEN_PUBLIC_HOST}: сервисы обращаются к Keycloak и IAM по публичному имени, чтобы issuer в токене совпадал с тем, что видит браузер.

Профили

По умолчанию make up поднимает core edge. Остальные профили включаются явно: make up PROFILES="core platform edge" или docker compose --profile core --profile edge up -d.

Профиль Статус Сервисы
core ядро iam-db, iam-service, control-plane-db, control-plane-api, control-plane-worker, context-adapter, memory-db, memory-service
edge ядро caddy
entitlement заморожен entitlement-db, entitlement-service
policy экспериментальный policy-db, openfga-migrate, openfga, policy-service, policy-worker
platform заморожен platform-db, platform-redis, realm-render, keycloak, minio, minio-bootstrap, platform-migrations, platform-api, platform-web
demo демо, не входит в поставку support-bot
fleet ядро агентов fleet-controller

Зависимости между профилями

depends_on работает только внутри активных профилей. Шлюз platform-api ходит в control-plane-api — поднимайте профили вместе (PROFILES="core platform edge").

Сводная таблица портов

Сервис Внутренний порт Публикуется на хосте Переменная порта Путь в Caddy
caddy 80, 443 0.0.0.0:80, 0.0.0.0:443 EDGE_HTTP_PORT, EDGE_HTTPS_PORT —
control-plane-api 8000 127.0.0.1:18000 CP_HOST_PORT /api/v1/*, /health/*, /metrics, /docs, /docs/*, /redoc, /redoc/*, /openapi.json
memory-service 8077 127.0.0.1:18001 MEMORY_HOST_PORT /memory/* (только в локальном Caddyfile)
iam-service 8010 127.0.0.1:18010 IAM_HOST_PORT /iam/* (префикс срезается)
entitlement-service 8020 127.0.0.1:18020 ENT_HOST_PORT нет
policy-service 8030 127.0.0.1:18040 POL_HOST_PORT нет
platform-api 8000 (и 9464 — метрики Prometheus, не публикуется) 127.0.0.1:18080 PLATFORM_API_HOST_PORT /platform/* (префикс срезается, X-Forwarded-Prefix: /platform)
keycloak 8080 (9000 — management, health) 127.0.0.1:18081 KEYCLOAK_HOST_PORT /auth/* (без среза, Keycloak живёт под /auth)
support-bot 8000 127.0.0.1:18090 SUPPORT_HOST_PORT /support-demo/* (префикс срезается; /support-demo → 301)
fleet-controller 8040 нет — /fleet/* (префикс срезается)
platform-web 3000 127.0.0.1:13000 PLATFORM_WEB_HOST_PORT / — всё, что не совпало выше
openfga 8080 нет — нет
platform-redis 6379 нет — нет
minio 9000 нет — нет
базы *-db 5432 нет — нет
control-plane-worker, context-adapter, policy-worker — нет — нет

Порядок маршрутов Caddy

Caddy выбирает первый совпавший handle. Специфичные префиксы (/iam/*, /auth/*, /platform/* …) и матчер Control Plane @cp_api стоят раньше общего handle, который отдаёт всё остальное веб-консоли. Добавляя свой маршрут, ставьте его перед общим handle.

Ядро (core)

iam-db

Параметр Значение
Образ postgres:16-alpine
БД / роль iam / iam, пароль ${IAM_POSTGRES_PASSWORD}
Volume iam_db → /var/lib/postgresql/data
Healthcheck pg_isready -U iam -d iam
Лимит памяти ${PG_MEM_LIMIT:-256m}

iam-service

Параметр Значение
Образ / сборка ${IMAGE_PREFIX}/iam-service:${IMAGE_TAG}, контекст ${IAM_BUILD_CONTEXT:-./iam-service}
Команда alembic upgrade head && uvicorn iam_service.app:app --host 0.0.0.0 --port 8010
Порт 8010 → 127.0.0.1:${IAM_HOST_PORT:-18010}
Зависит от iam-db (healthy)
Секреты iam_signing_key → /run/secrets/iam_signing_key (файл ${IAM_SIGNING_KEY_FILE})
Healthcheck GET http://127.0.0.1:8010/healthz
Лимит памяти ${IAM_MEM_LIMIT:-256m}
Пользователь uid 10001

control-plane-db

Параметр Значение
Образ postgres:16-alpine
БД / роль control_plane / control_plane
Volume control_plane_db
Healthcheck pg_isready -U control_plane -d control_plane
Лимит памяти ${PG_MEM_LIMIT:-256m}

control-plane-api

Параметр Значение
Образ / сборка ${IMAGE_PREFIX}/control-plane:${IMAGE_TAG}, контекст ${CP_BUILD_CONTEXT:-.} (корень суперпроекта), Dockerfile control-plane/Dockerfile
Команда alembic upgrade head && uvicorn control_plane.main:app --host 0.0.0.0 --port 8000
Порт 8000 → 127.0.0.1:${CP_HOST_PORT:-18000}
Зависит от control-plane-db, memory-service, iam-service (все healthy)
env_file ./secrets/control-plane-iam.env (необязательный)
Healthcheck GET http://127.0.0.1:8000/health/ready
Лимит памяти ${CP_MEM_LIMIT:-512m}
Пользователь uid 10001

control-plane-worker

Параметр Значение
Образ тот же, что у control-plane-api (не собирается отдельно)
Команда python -m control_plane.worker
Порт нет
Зависит от control-plane-db (healthy), control-plane-api (healthy)
env_file ./secrets/control-plane-iam.env
Healthcheck нет
Лимит памяти ${CP_WORKER_MEM_LIMIT:-256m}

context-adapter

Параметр Значение
Образ тот же, что у control-plane-api
Команда python -m control_plane.worker.context_adapter
Порт нет
Зависит от control-plane-db, control-plane-api, memory-service (все healthy)
env_file ./secrets/control-plane-iam.env
Healthcheck нет
Лимит памяти ${CP_WORKER_MEM_LIMIT:-256m}

Один образ на три процесса

control-plane-api, control-plane-worker и context-adapter работают на одном образе. Образ собирается только сервисом control-plane-api; после сборки пересоздайте все три контейнера, иначе worker и адаптер останутся на прежнем коде.

memory-db

Параметр Значение
Образ / сборка ${IMAGE_PREFIX}/memory-db:${IMAGE_TAG}, контекст ${MEMORY_BUILD_CONTEXT:-./memory-service}/infra/memory-db (PostgreSQL 16 + Apache AGE + pgvector)
БД / роль company_brain / memory
Volume memory_db
Healthcheck pg_isready -U memory -d company_brain
Лимит памяти ${MEMORY_DB_MEM_LIMIT:-512m}

memory-service

Параметр Значение
Образ / сборка ${IMAGE_PREFIX}/memory-service:${IMAGE_TAG}, контекст ${MEMORY_BUILD_CONTEXT:-.}, Dockerfile memory-service/Dockerfile
Порт 8077 → 127.0.0.1:${MEMORY_HOST_PORT:-18001}
Зависит от memory-db (healthy)
env_file ./secrets/memory-service-iam.env (необязательный)
Healthcheck GET http://127.0.0.1:8077/healthz
Лимит памяти ${MEMORY_MEM_LIMIT:-512m}

Периметр (edge)

caddy

Параметр Значение
Образ caddy:2-alpine
Порты ${EDGE_HTTP_PORT:-80}:80, ${EDGE_HTTPS_PORT:-443}:443 на всех интерфейсах
Volumes ${CADDYFILE} → /etc/caddy/Caddyfile (read-only), caddy_data → /data (сертификаты ACME), caddy_config → /config
Сетевой alias ${TAIMEN_PUBLIC_HOST:-taimen.localhost}
Healthcheck нет

Локальный deploy/caddy/Caddyfile.local обслуживает http://taimen.localhost и http://localhost без ACME, пишет лог в stderr и сжимает ответы (zstd, gzip). Промышленный Caddyfile задаётся переменной CADDYFILE и повторяет ту же раскладку путей с TLS, но без маршрута /memory/*: память наружу не публикуется. Подробнее — Периметр и TLS.

Правка Caddyfile на месте

Файл смонтирован bind-mount'ом и держит inode. Если заменить файл через mv, caddy reload перечитает старую версию. Правьте файл на месте или пересоздайте контейнер: docker compose up -d --force-recreate caddy.

Entitlement (entitlement, заморожен)

Сервис Образ / сборка Порт Зависит от Volume Healthcheck Лимит
entitlement-db postgres:16-alpine, БД entitlement — — entitlement_db pg_isready -U entitlement -d entitlement ${PG_MEM_LIMIT}
entitlement-service контекст ${ENT_BUILD_CONTEXT:-.}, Dockerfile entitlement-service/Dockerfile; команда alembic upgrade head && uvicorn entitlement_service.app:app --port 8020 8020 → 127.0.0.1:18020 entitlement-db секрет entitlement_signing_key нет ${ENT_MEM_LIMIT:-256m}

Policy (policy, экспериментальный)

Сервис Образ / сборка Порт Зависит от Volume / файлы Healthcheck Лимит
policy-db postgres:16-alpine, БД policy и openfga — — policy_db; policy-service/deploy/init-openfga.sql → init-скрипт pg_isready -U policy -d policy ${PG_MEM_LIMIT}
openfga-migrate openfga/openfga:v1.20.0, migrate (одноразовый) — policy-db (healthy) — — —
openfga openfga/openfga:v1.20.0, run, playground выключен, логи JSON 8080, не публикуется openfga-migrate (завершён успешно) — /openfga version ${OPENFGA_MEM_LIMIT:-256m}
policy-service контекст ${POL_BUILD_CONTEXT:-.}, Dockerfile policy-service/Dockerfile; alembic upgrade head && uvicorn policy_service.app:app --port 8030 8030 → 127.0.0.1:18040 policy-db, openfga (healthy) — GET /healthz ${POL_MEM_LIMIT:-256m}
policy-worker образ policy-service, команда policy-worker — policy-service (healthy) env_file ./secrets/policy-service-cp.env нет ${POL_MEM_LIMIT:-256m}

Панель платформы (platform, заморожен)

Сервис Образ / сборка Порт Зависит от Volume / файлы Healthcheck Лимит
platform-db postgres:16-alpine, БД platform + БД keycloak (init-скрипт) — — platform_db; deploy/staging/platform/postgres/init-keycloak-db.sh pg_isready -U platform -d platform (10 s × 10) ${PG_MEM_LIMIT}
platform-redis redis:7-alpine, AOF, пароль — — platform_redis → /data redis-cli ping ${REDIS_MEM_LIMIT:-128m}
realm-render busybox:1.36, одноразовый: подставляет секрет клиента и адрес веба в шаблон realm — — deploy/staging/platform/keycloak → /template, realm_import → /import — —
keycloak quay.io/keycloak/keycloak:26.5.2, start --import-realm 8080 → 127.0.0.1:18081 platform-db (healthy), realm-render (завершён) realm_import (read-only) GET /auth/health/ready на порту 9000 (15 s × 20, start 40 s) ${KEYCLOAK_MEM_LIMIT:-768m}
minio minio/minio:RELEASE.2024-10-13T13-34-11Z, server /data 9000, не публикуется — platform_minio mc ready local ${MINIO_MEM_LIMIT:-256m}
minio-bootstrap minio/mc:RELEASE.2024-10-08T09-37-26Z, одноразовый: создаёт бакет ${S3_BUCKET} — minio (healthy) — — —
platform-migrations контекст ${PLATFORM_BUILD_CONTEXT:-./platform-core}, Dockerfile workers/migrations/Dockerfile, одноразовый — platform-db (healthy) — — —
platform-api тот же контекст, Dockerfile apps/api/Dockerfile, UVICORN_ROOT_PATH=/platform 8000 → 127.0.0.1:18080 platform-db, platform-redis (healthy), platform-migrations, minio-bootstrap (завершены) — из образа: GET /health (15 s × 6, start 20 s) ${PLATFORM_API_MEM_LIMIT:-512m}
platform-web контекст ${PLATFORM_WEB_BUILD_CONTEXT:-./platform-web}, build-args NEXT_PUBLIC_* 3000 → 127.0.0.1:13000 platform-api (healthy) — из образа: wget на :3000 (30 s × 3) ${PLATFORM_WEB_MEM_LIMIT:-512m}

Realm импортируется один раз

--import-realm импортирует realm только при первом старте с пустой БД. Правки шаблона на существующий realm не попадают — меняйте живой realm через Admin API. См. Вход людей — Keycloak.

Fleet (fleet)

Контроллер узлов и размещения декларативных агентов (TAI-ADR-0052). Узлы (fleet-node) работают на машинах исполнителей вне этого compose и ходят к контроллеру только исходящими запросами через Caddy /fleet/*.

Сервис Образ / сборка Порт Зависит от Volume / env Healthcheck Лимит
fleet-controller ${IMAGE_PREFIX:-taimen}/fleet-controller:${IMAGE_TAG:-local}, контекст ${FLEET_BUILD_CONTEXT:-.}, Dockerfile fleet/Dockerfile; команда fleet-controller serve 8040, не публикуется control-plane-api, iam-service (healthy) fleet_data → /data; env_file ./secrets/fleet-iam.env GET /healthz на 127.0.0.1:8040 ${FLEET_MEM_LIMIT:-128m}

Без secrets/fleet-iam.env (bootstrap, шаг 5d) все маршруты, кроме /healthz, отвечают 503 not_configured. Переменные — в Переменных окружения, устройство — в Узлах и fleet.

Демо

Сервис Профиль Образ / сборка Порт Volume Healthcheck Лимит
support-bot demo контекст ${SUPPORT_BUILD_CONTEXT:-.}, Dockerfile demos/support-demo/Dockerfile 8000 → 127.0.0.1:18090 support_data → /srv/data GET /api/config (10 s × 12) ${SUPPORT_MEM_LIMIT:-256m}

support-bot не объявляет depends_on: memory-service и Control Plane должны быть подняты заранее.

Коннектор git — агент, а не сервис compose

Источник наблюдений git в compose.yml платформы не входит: это агент вида исполнителя git-connector, которого запускает узел fleet (образ integrations/selfdev/Dockerfile, том реплики — fleet-<agent>-<replica>-data, токен forge — секрет узла github-token). См. Узлы и fleet.

Healthcheck'и и smoke

У Python-сервисов ядра общий шаблон healthcheck: интервал 5 s, таймаут 5 s, 30 попыток; проверка — urllib.request.urlopen на 127.0.0.1 (не localhost: в slim-образах localhost может резолвиться в IPv6 ::1, где сервер не слушает).

make smoke (tools/smoke.py) проверяет поднятые сервисы по портам на 127.0.0.1 и пропускает не запущенные:

Сервис Порт по умолчанию Путь
iam-service 18010 /healthz
control-plane-api 18000 /health/ready
memory-service 18001 /healthz
entitlement-service 18020 /healthz
platform-api 18080 /health
keycloak 18081 /auth/realms/platform
platform-web 13000 /
support-bot 18090 /api/config

Ответ с кодом < 400 — OK, иначе ERR и ненулевой код выхода. policy-service в smoke не входит.

Volumes

Volume Сервис Что хранит
iam_db iam-db Tenants, principals, credentials IAM
control_plane_db control-plane-db Work graph, журнал событий, bindings
memory_db memory-db Граф знаний, чанки, наблюдения
entitlement_db entitlement-db Лицензии, квоты
policy_db policy-db Роли, bindings и store OpenFGA
platform_db platform-db БД platform и keycloak
platform_redis platform-redis Кэш, брокер событий
platform_minio minio Документы
realm_import realm-render, keycloak Отрендеренный realm
support_data support-bot SQLite демо
fleet_data fleet-controller SQLite: узлы, размещения, личности агентов, шифротексты PAT
caddy_data, caddy_config caddy Сертификаты и состояние Caddy

Имена задаются переменными VOLUME_* (см. Переменные окружения). make down volumes не удаляет.

Docker-секреты

Секрет Файл по умолчанию Кому
iam_signing_key ./secrets/iam-signing.pem iam-service
entitlement_signing_key ./secrets/entitlement-signing.pem entitlement-service

Контейнеры читают секреты под непривилегированным uid (10001 у сервисов ядра). На Linux выполните chown 10001 для файлов в secrets/, права оставьте 600.

См. также