16 KiB
Конфигурация проекта dps-message-hub
Версия: 0.1.0
Документ описывает все переменные окружения и способы конфигурирования сервиса.
dps-message-hub (dps_message_hub) — это Kafka-воркер на базе FastStream, потребляющий сообщения об изменении ассетов и обновляющий данные разметки (markup_event) в PostgreSQL домена «documentations». HTTP API у сервиса нет.
Это отдельный сервис, не путать с приложением
message-hub(доменplanning): у них разные префиксы переменных, набор интеграций и назначение.
Способы конфигурирования
Сервис настраивается только через переменные окружения. Разбор выполняется в src/dps_message_hub/infra/config.py через библиотеку pydantic-settings (класс AppSettings(BaseSettings)).
Особенности разбора (SettingsConfigDict):
env_prefix="DPS_MESSAGE_HUB_"— все переменные приложения начинаются с этого префикса;env_nested_delimiter="__"— вложенные секции задаются двойным подчёркиванием, напр.DPS_MESSAGE_HUB_DOCUMENTATION_DB__HOST→documentation_db.host;env_ignore_empty=False— пустая строка считается заданным значением (не игнорируется);frozen=True— объект настроек неизменяем после инициализации.
Настройки разбиты на три вложенные секции (модели pydantic.BaseModel), читаемые одним классом AppSettings:
app(App) — префиксDPS_MESSAGE_HUB_APP__;documentation_db(Database) — префиксDPS_MESSAGE_HUB_DOCUMENTATION_DB__;kafka(Kafka) — префиксDPS_MESSAGE_HUB_KAFKA__.
Класс Settings (src/dps_message_hub/infra/config.py) — синглтон (wiring.SingletonMeta) поверх AppSettings, отдаёт настройки через свойство .settings.
Отдельного конфиг-файла (yaml/toml) у приложения нет. У классов настроек не задан env_file, поэтому файл .env автоматически не загружается — переменные нужно экспортировать в окружение процесса самостоятельно (make config лишь копирует .example.env → .env как шаблон), либо пробрасывать их в контейнер через --env-file (см. Makefile, цель container-run).
Источники переменных по способам запуска:
| Способ запуска | Откуда берутся переменные |
|---|---|
| Локально (бинарник) | Переменные окружения процесса. make config копирует .example.env → .env, но приложение не загружает .env автоматически — экспортируйте сами, напр. set -a && . ./.env && set +a |
| Локально (контейнер) | Makefile: цель container-run пробрасывает переменные через --env-file .env |
| Kubernetes (Helm) | .helm/values.yaml: блок universal-chart.services.api.envs (обычные значения) и secretEnvs (значения из k8s-секретов); базовый чарт — universal-chart (oci://.../charts, версия 0.1.7) |
| CI/CD (GitLab) | .gitlab-ci.yml: переменные пайплайна (workflow.rules) и HELM_SET_ARGS |
Запуск процесса (scripts/entrypoint.sh): единый FastStream-процесс с брокером Kafka:
faststream run \
--factory \
--workers ${DPS_MESSAGE_HUB_NUM_WORKERS} \
'dps_message_hub.infra.app:get_app'
Фабрика dps_message_hub.infra.app:get_app (src/dps_message_hub/infra/app.py) собирает FastStream-приложение: создаёт KafkaBroker, подключает роутер-потребитель топика assets и открывает пул соединений PostgreSQL в lifespan. Отдельных точек входа для воркеров/крон-задач нет — pyproject.toml не содержит [project.scripts].
Переменные приложения
Дефолт — означает, что значение обязательно (иначе ошибка старта настроек).
Приложение (DPS_MESSAGE_HUB_APP__*) — класс App
| Переменная | Тип | Значение по умолчанию | Назначение |
|---|---|---|---|
DPS_MESSAGE_HUB_APP__LOG_LEVEL |
enum (LogLevel) |
INFO |
Уровень логирования. Допустимо: CRITICAL/FATAL/ERROR/WARNING/WARN/INFO/DEBUG/NOTSET |
DPS_MESSAGE_HUB_APP__IS_DEV |
bool | False |
Признак dev-режима. Поле объявлено в настройках, но в текущем коде не используется |
DPS_MESSAGE_HUB_APP__BROKER_TYPE |
enum (BrokerType) |
— (обязательно) |
Тип брокера сообщений. Поддерживается только значение kafka |
База данных PostgreSQL (DPS_MESSAGE_HUB_DOCUMENTATION_DB__*) — класс Database
| Переменная | Тип | Значение по умолчанию | Назначение |
|---|---|---|---|
DPS_MESSAGE_HUB_DOCUMENTATION_DB__HOST |
string | — |
Хост PostgreSQL |
DPS_MESSAGE_HUB_DOCUMENTATION_DB__PORT |
int | — |
Порт PostgreSQL |
DPS_MESSAGE_HUB_DOCUMENTATION_DB__USER |
string | — |
Пользователь БД |
DPS_MESSAGE_HUB_DOCUMENTATION_DB__PASSWORD |
string | — |
Пароль пользователя БД |
DPS_MESSAGE_HUB_DOCUMENTATION_DB__NAME |
string | — |
Имя базы данных |
DPS_MESSAGE_HUB_DOCUMENTATION_DB__ENABLE_SSL |
bool | — |
Включить TLS-подключение к БД |
DPS_MESSAGE_HUB_DOCUMENTATION_DB__SSL_MODE |
enum (verify-full/verify-ca/"") |
— |
Режим проверки TLS (параметр sslmode DSN). При ENABLE_SSL=true не должно быть пустым |
DPS_MESSAGE_HUB_DOCUMENTATION_DB__SSL_ROOT_CERT_PATH |
string | — |
Путь к CA-сертификату (параметр sslrootcert DSN). При ENABLE_SSL=true не должно быть пустым |
Валидатор check_ssl_options_configured_when_ssl_enabled: если ENABLE_SSL=true, то SSL_MODE и SSL_ROOT_CERT_PATH обязаны быть непустыми, иначе ошибка старта. Итоговый DSN собирается в вычисляемом поле documentation_db.uri (postgresql://user:password@host:port/name, при SSL добавляются ?sslmode=...&sslrootcert=...).
Kafka (DPS_MESSAGE_HUB_KAFKA__*) — класс Kafka
| Переменная | Тип | Значение по умолчанию | Назначение |
|---|---|---|---|
DPS_MESSAGE_HUB_KAFKA__HOST |
string | — |
Хост брокера Kafka |
DPS_MESSAGE_HUB_KAFKA__PORT |
int | — |
Порт брокера Kafka |
DPS_MESSAGE_HUB_KAFKA__USERNAME |
string | — |
Логин SASL (SCRAM-SHA-512) |
DPS_MESSAGE_HUB_KAFKA__PASSWORD |
string | — |
Пароль SASL (SCRAM-SHA-512) |
DPS_MESSAGE_HUB_KAFKA__SSL_CAFILE |
string | null | None |
Путь к CA-сертификату для SSL-контекста. Если задан — используется SASL_SSL, иначе SASL без TLS |
DPS_MESSAGE_HUB_KAFKA__TOPICS |
dict (JSON) → KafkaTopics |
— |
Соответствие логического топика реальному имени в Kafka. Обязателен ключ assets, напр. {"assets": "assets_broadcast"} |
Формирование параметров подключения (src/dps_message_hub/infra/app.py): адрес брокера — вычисляемое поле kafka.uri (host:port). Безопасность через faststream.security.SASLScram512:
- если заданы
USERNAMEиPASSWORDиSSL_CAFILEпуст —SASLScram512(..., use_ssl=False); - если задан
SSL_CAFILE—SASLScram512(..., ssl_context=create_ssl_context(cafile=...)).
Переменные инфраструктуры, сборки и запуска
Не читаются классами настроек приложения, но участвуют в запуске/сборке/деплое.
| Переменная | Где используется | Назначение |
|---|---|---|
DPS_MESSAGE_HUB_NUM_WORKERS |
scripts/entrypoint.sh, Helm envs |
Число воркеров FastStream (faststream run --workers). В Helm _default: '2' |
DPS_MESSAGE_HUB_PYTHON_IMAGE_NAME |
Dockerfile (ARG) |
Базовый образ Python (по умолчанию python) |
DPS_MESSAGE_HUB_PYTHON_IMAGE_TAG |
Dockerfile (ARG) |
Тег базового образа (по умолчанию 3.13-slim) |
PIP_INDEX_URL, PIP_TRUSTED_HOST |
Dockerfile (ARG) |
Индекс/доверенный хост pip при сборке |
Сборка (Dockerfile): многостадийная — стадия builder собирает wheel'ы из requirements/requirements.txt, стадия runner ставит их, копирует src/ и устанавливает пакет (pip install . --no-deps); процесс запускается непривилегированным пользователем dps_message_hub. Целевая версия Python — 3.13 (.python-version, requires-python >=3.13).
Переменные из Helm-чарта (.helm/values.yaml)
Сервис деплоится через зависимость universal-chart (.helm/Chart.yaml, версия 0.1.7). Настраивается один сервис — services.api (тип нагрузки — deployment, replicaCount._default: 1). HTTP-service и ingress отключены, health-пробы (liveness/readiness, путь /ping) — enabled: false (у сервиса нет HTTP-эндпоинтов).
Обычные значения (блок services.api.envs) различаются по окружениям (_default/stage/preprod/production) адресами БД и Kafka, именем БД и именами топиков. В Helm дополнительно заданы (отсутствуют в .example.env): DPS_MESSAGE_HUB_KAFKA__HOST, DPS_MESSAGE_HUB_KAFKA__PORT (9091), DPS_MESSAGE_HUB_KAFKA__SSL_CAFILE (/opt/config/ca.crt), DPS_MESSAGE_HUB_DOCUMENTATION_DB__ENABLE_SSL=true, SSL_MODE=verify-full, SSL_ROOT_CERT_PATH=/opt/config/ca.crt.
Значения из секретов (блок secretEnvs, монтируются как env через secretKeyRef):
| Переменная | Секрет (_default / stage) |
Ключ (secretKey) |
|---|---|---|
DPS_MESSAGE_HUB_DOCUMENTATION_DB__USER |
ya-pg-secret / documentations-postgresql-secret |
username |
DPS_MESSAGE_HUB_DOCUMENTATION_DB__PASSWORD |
ya-pg-secret / documentations-postgresql-secret |
password |
DPS_MESSAGE_HUB_KAFKA__USERNAME |
kafka-secret |
username |
DPS_MESSAGE_HUB_KAFKA__PASSWORD |
kafka-secret |
password |
Помимо env, чарт монтирует CA-сертификат Яндекса из ConfigMap ya-ca-cert (ключ ca.crt) как файл /opt/config/ca.crt (том cm-ya-ca-cert, readOnly) — на него указывают DPS_MESSAGE_HUB_KAFKA__SSL_CAFILE и DPS_MESSAGE_HUB_DOCUMENTATION_DB__SSL_ROOT_CERT_PATH.
Переменные в CI (.gitlab-ci.yml)
Пайплайн подключает общие шаблоны из generic/common-ci (common-security-scan.yaml, universal-pipeline.yaml, ref apps-business) и переключает окружение по ветке/тегу через workflow.rules:
| Условие | STAND | NAMESPACE | CHART_VERSION | K8S_HUSTLER_BRANCH |
|---|---|---|---|---|
MR (merge_request_event) |
— | — | — | сборка образа отключена (ENABLE_BUILD_IMAGE=false) |
ветка stage |
stage |
documentations |
0.0.1-stage |
stage |
ветка master |
preprod |
documentations-preprod |
0.0.1-preprod |
preprod |
тег (CI_COMMIT_TAG) |
prod |
documentations-prod |
0.0.1-prod |
master |
Ключевые переменные пайплайна: SERVICE_NAME=dps-message-hub, DOCKERFILE_PATH=Dockerfile, CI_TRIGGER_SOURCE=app, RELEASE_NAME=dps-message-hub, CHART_NAME=dps-message-hub, флаги ENABLE_BUILD_CHART/ENABLE_BUILD_IMAGE/ENABLE_DEPLOY, HELM_SET_ARGS (--set universal-chart...). Отдельные job'ы format (ruff format --diff) и lint (ruff check) на образе python:3.13-slim.
Замечания и потенциальные проблемы
- Приложение не читает
.envавтоматически (вSettingsConfigDictнетenv_file).make configтолько создаёт.envиз шаблона — переменные нужно экспортировать самому либо передавать контейнеру через--env-file. - Большинство полей БД и Kafka обязательны (без дефолтов): при пустом окружении настройки не пройдут валидацию и сервис не стартует. Единственные необязательные —
APP__LOG_LEVEL,APP__IS_DEV,KAFKA__SSL_CAFILE. DPS_MESSAGE_HUB_APP__BROKER_TYPEобязателен; поддерживается толькоkafka(иных веток вmatchнет). При другом значении брокер не будет создан.- При
ENABLE_SSL=trueобязательно задаватьSSL_MODEиSSL_ROOT_CERT_PATH, иначе валидатор настроек прервёт старт. DPS_MESSAGE_HUB_KAFKA__TOPICSобязан содержать ключassets(модельKafkaTopics); прочие ключи игнорируются, отсутствиеassets— ошибка старта.- Поле
APP__IS_DEVприсутствует в настройках, но в текущем коде нигде не задействовано. - Обработка Kafka-сообщений идёт с
auto_commit=Falseи middlewareRetry(src/dps_message_hub/interface/middleware.py), которая повторяет обработку бесконечно с экспоненциальной задержкой (до1<<10 = 1024сек) — «отравленное» сообщение может заблокировать партицию.
Минимальный набор для локального запуска
Kafka и Zookeeper поднимаются через Makefile (цели run-deps/run-zookeeper/run-kafka); PostgreSQL — внешний. Минимально нужно задать:
DPS_MESSAGE_HUB_APP__BROKER_TYPE=kafka;DPS_MESSAGE_HUB_DOCUMENTATION_DB__HOST,__PORT,__USER,__PASSWORD,__NAME,__ENABLE_SSL(для локалиfalse),__SSL_MODE,__SSL_ROOT_CERT_PATH(приENABLE_SSL=falseможно пустыми);DPS_MESSAGE_HUB_KAFKA__HOST,__PORT,__USERNAME,__PASSWORD,__TOPICS(JSON с ключомassets);DPS_MESSAGE_HUB_NUM_WORKERS(дляentrypoint.sh).
Локальный запуск: make run (через entrypoint.sh) либо make run-dev (faststream run --factory --reload dps_message_hub.infra.app:get_app). Готовые значения-примеры приведены в dps-message-hub.env.example рядом с этим документом.