iac/apps/processing/workflows-engine.CONFIGURATION.md

364 lines
30 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Конфигурация проекта workflows-engine
`workflows-engine` (внутреннее имя образа — `kubernetes-engine`) — это фоновый сервис-оркестратор (демон без REST API), который вычитывает workflow/задачи из PostgreSQL и запускает их либо как Job'ы в Kubernetes, либо публикует в RabbitMQ (AMQP-исполнитель). Конфигурируется исключительно через переменные окружения.
## Способы конфигурирования
- **Библиотека парсинга:** [`github.com/ilyakaznacheev/cleanenv`](https://github.com/ilyakaznacheev/cleanenv).
- **Точка входа конфигурации:** `config/config.go`, функция `config.New()` вызывает `cleanenv.ReadEnv(cfg)` и заполняет структуру `Config` из переменных окружения процесса.
- **Формат тегов:** каждое поле помечено тегом `env:"ИМЯ"`; значение по умолчанию задаётся тегом `env-default:"..."`. Префикса имён переменных нет.
- **Составная структура `Config`** собирается из встроенных (embedded) структур:
- `App`, `Log`, `Executor`, `Kubernetes`, `Resources`, `Storages`, `Pooling`, `Workflows`, `Security` — объявлены в `config/config.go`;
- `pgxconnection.Postgres` — объявлена в `pkg/pgxconnection/postgres.go` (переменные `POSTGRES_*`);
- `rabbitmq.RabbitMQ` — объявлена в `pkg/rabbitmq/config.go` (переменные `RABBITMQ_*`).
- **Кастомный парсинг:** поле `WORKFLOW_PRIORITY` имеет тип `entity.WorkflowPriority` с методом `SetValue` (`internal/entity/workflow.go`); допустимые значения: `default`, `high`, `low` (регистр не важен).
- **Важно:** часть переменных из `config.env` и Helm-чарта **не читается** структурой конфигурации. Они либо читаются напрямую через `os.Getenv(...)` в `pkg/kube_services/services.go` и **пробрасываются в env запускаемых Job-подов** (а не потребляются самим engine), либо не используются кодом вовсе (см. раздел «Замечания и потенциальные проблемы»).
### Режимы запуска / исполнители
Бинарь один (`cmd/engine`), «режим» определяется набором включённых исполнителей и приоритетом.
| Режим | Как включается | Назначение |
| --- | --- | --- |
| Kubernetes-исполнитель | `ENABLE_KUBERNETES_EXECUTOR=1` (по умолчанию `true`) | Запуск задач как `batchv1.Job` в кластере Kubernetes |
| AMQP-исполнитель | `ENABLE_AMQP_EXECUTOR=1` (по умолчанию `false`) | Публикация задач в RabbitMQ и приём результатов |
| backend (обычный приоритет) | Helm-деплой `backend`, `WORKFLOW_PRIORITY=low` | Обработка обычных workflow |
| backend-high-priority | Helm-деплой `backend-high-priority`, `WORKFLOW_PRIORITY=high` | Обработка высокоприоритетных workflow |
Оба Helm-деплоя разворачивают один и тот же образ; отличаются только значением `WORKFLOW_PRIORITY``MAX_WORKFLOWS_LIMIT`).
### Точки входа (entrypoints)
| Путь | Тип | Описание |
| --- | --- | --- |
| `cmd/engine/main.go` | main-пакет | Единственная точка входа. Поднимает pprof-сервер на `:8081`, читает конфиг, создаёт `engine.New(cfg, logger)` и вызывает `Run()` |
| `internal/apps/engine/engine.go` | приложение | Основная логика: подключение к Postgres, инициализация исполнителей (K8s/AMQP), pooling-контроллер и оркестратор, graceful shutdown по SIGINT |
### Запуск контейнера
- **Dockerfile:** multi-stage сборка на `golang:1.20-buster`, финальный образ `FROM scratch`.
- **CMD/ENTRYPOINT:** `ENTRYPOINT ["/engine"]` — запускается собранный бинарь напрямую, без shell-скрипта/entrypoint-обёртки.
- Внутри процесса дополнительно поднимается HTTP-сервер `net/http/pprof` на порту `:8081` (профилирование). Полноценного REST API нет (см. раздел про `API_ADDRESS`).
## Переменные приложения
### Приложение и логирование (`App`, `Log`)
| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `APP_NAME` | string | `kubernetes-engine` | Имя приложения (в Helm переопределяется на `kubernetes-engine`/`kubernetes-engine-high-priority`) |
| `APP_VERSION` | string | `v1` | Версия приложения |
| `LOG_LEVEL` | string | `info` | Уровень логирования |
### PostgreSQL (`pkg/pgxconnection`)
| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `POSTGRES_ADDRESS` | string | `localhost` | Хост БД |
| `POSTGRES_DB` | string | `processing_db` | Имя базы данных |
| `POSTGRES_USER` | string | `user` | Пользователь БД |
| `POSTGRES_PASSWORD` | string | `password` | Пароль БД |
| `POSTGRES_PORT` | string | `5432` | Порт БД |
| `POSTGRES_POOL_SIZE` | int | `20` | Размер пула соединений |
| `ENABLE_SQL_QUERY` | bool | `true` | Логирование SQL-запросов |
| `YC-PG-CERTIFICATE` | string | `""` | TLS-сертификат CA для подключения к БД (значение сертификата) |
| `POSTGRES_SSL_USE` | bool | `false` | Использовать SSL при подключении к БД |
### RabbitMQ (`pkg/rabbitmq`) — используется только при `ENABLE_AMQP_EXECUTOR=1`
| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `RABBITMQ_HOST` | string | — | Хост брокера |
| `RABBITMQ_PORT` | string | — | Порт брокера |
| `RABBITMQ_USER` | string | — | Пользователь |
| `RABBITMQ_PASS` | string | — | Пароль |
| `RABBITMQ_VHOST` | string | — | Виртуальный хост |
| `RABBITMQ_USE_SSL` | bool | — | Использовать TLS |
| `RABBITMQ_CERTIFICATE` | string | — | TLS-сертификат |
| `RABBITMQ_CREATE_EXCHANGE` | string | — | Exchange для отправки задач на запуск |
| `RABBITMQ_CANCEL_EXCHANGE` | string | — | Exchange для отмены задач |
| `RABBITMQ_CREATE_ROUTING_KEY` | string | — | Routing key для запуска |
| `RABBITMQ_CANCEL_TOPIC` | string | — | Topic/ключ отмены |
| `RABBITMQ_COMPLETENESS_EXCHANGE` | string | — | Exchange для получения результатов выполнения |
| `RABBITMQ_COMPLETENESS_TOPIC` | string | — | Topic результатов выполнения |
> Примечание: в `config.env` присутствуют также `RABBITMQ_CREATE_TOPIC` — переменной `RABBITMQ_CREATE_TOPIC` в коде нет (в структуре есть только `CreateRoutingKey`).
### Исполнители и воркеры (`Executor`)
| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `COUNT_RUNNING_WORKERS` | int | — (0) | Кол-во воркеров запуска задач |
| `COUNT_CANCELING_WORKERS` | int | — (0) | Кол-во воркеров отмены задач |
| `COUNT_HANDLE_JOB_WORKERS` | int | — (0) | Кол-во воркеров обработки Job'ов |
| `ENABLE_AMQP_EXECUTOR` | bool | `false` | Включить AMQP-исполнитель (RabbitMQ) |
| `ENABLE_KUBERNETES_EXECUTOR` | bool | `true` | Включить Kubernetes-исполнитель |
### Kubernetes (`Kubernetes`)
| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `JOBS_NAMESPACE` | string | — | Namespace, в котором создаются Job'ы задач |
| `KUBE_CONFIG` | string | — | Путь к kubeconfig. Если **пусто** — используется in-cluster конфигурация; если задан — out-of-cluster |
| `KUBE_CONTEXT` | string | — | Контекст kubeconfig (для out-of-cluster) |
| `KUBE_ADDR` | string | — | Адрес API-сервера кластера (для out-of-cluster; используется с `InsecureSkipTLSVerify`) |
### Ресурсы и планирование подов (`Resources`)
Управляют NodeSelector/Tolerations/requests для запускаемых Job'ов в зависимости от `service_requests` задачи (см. `README.md`).
| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `CPU_COUNT` | int | — | CPU requests для `high-resources`/`persistent` |
| `MEMORY_GI` | int | — | Memory (Gi) requests для `high-resources`/`persistent` |
| `CPU_COUNT_LOW_RESOURCES` | int | — | CPU для `low-resources` |
| `MEMORY_GI_LOW_RESOURCES` | int | — | Memory (Gi) для `low-resources` |
| `CPU_COUNT_HIGH_MEM` | int | — | CPU для `super-high-resources` |
| `MEMORY_GI_HIGH_MEM` | int | — | Memory (Gi) для `super-high-resources` |
| `ENABLE_TOLERATION` | bool | — | Включить набор сервисов ресурсов (toleration/nodeselector) |
| `TOLERATION_KEY` | string | — | Ключ toleration/nodeselector для high/low ресурсов |
| `TOLERATION_VALUE` | string | — | Значение toleration/nodeselector для high/low ресурсов |
| `TOLERATION_KEY_HIGH_MEM` | string | — | Ключ toleration для `super-high-resources` |
| `TOLERATION_VALUE_HIGH_MEM` | string | — | Значение toleration для `super-high-resources` |
| `TOLERATION_KEY_PERSISTENT` | string | — | Ключ toleration для `persistent` |
| `TOLERATION_VALUE_PERSISTENT` | string | — | Значение toleration для `persistent` |
| `DJANGO_BASIC_AUTH` | string | — | Базовая авторизация Django (поле присутствует в конфиге, но не используется в бизнес-логике; в под задачи прокидывается хардкод-путь `DJANGO_BASIC_AUTH_PATH`) |
| `DEFAULT_TOLERATION_KEY` | string | — | Ключ toleration по умолчанию для всех подов |
| `DEFAULT_TOLERATION_VALUE` | string | — | Значение toleration по умолчанию |
| `DEFAULT_NODE_SELECTOR_KEY` | string | — | Ключ NodeSelector по умолчанию |
| `DEFAULT_NODE_SELECTOR_VALUE` | string | — | Значение NodeSelector по умолчанию |
| `DEFAULT_IMAGE_PULL_POLICY` | string | `always` | ImagePullPolicy для подов задач |
| `DEFAULT_CPU_REQUESTS` | string | `100m` | CPU requests по умолчанию |
| `DEFAULT_MEMORY_REQUESTS` | string | `64Mi` | Memory requests по умолчанию |
### Хранилища и внешние сервисы (`Storages`)
Флаги `ENABLE_*` включают соответствующий «сервис» (набор env/секретов/volume), который добавляется в под задачи в зависимости от `service_requests`. URL'ы прокидываются в поды mesh/pdm-сервисов.
| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `S3_SERVICE_ACCOUNT` | string | — | Путь к service account JSON для S3 (в коде для подов путь по факту хардкодится) |
| `ENABLE_S3_STORAGE` | bool | — | Включить сервис `s3` |
| `ENABLE_S3V2_STORAGE` | bool | — | Включить сервис `s3v2` |
| `ENABLE_PDM_STORAGE` | bool | — | Включить сервис `pdm` |
| `ENABLE_URL_STORAGE` | bool | — | Включить сервис `url` |
| `ENABLE_LOCAL` | bool | — | Включить локальное хранилище |
| `ENABLE_BIM_API_DB` | bool | — | Включить сервис `bim_api_db` |
| `ENABLE_BIM_API_CH` | bool | — | Включить сервис `bim_api_ch` (ClickHouse) |
| `ENABLE_BIM_API_V2_DB` | bool | — | Включить сервисы `bim_api_v2_db` (+ db_2/3/4) |
| `ENABLE_PDM_API_DB` | bool | — | Включить сервис `pdm_api_db` |
| `ENABLE_COMPARISONS_API_DB` | bool | — | Включить сервис `comparison-api-db` |
| `ENABLE_ISSUE_API_DB` | bool | — | Включить сервис `issues-api-db` |
| `ENABLE_RESOURCES_API` | bool | — | Включить сервис `resources-api` |
| `ENABLE_MAIL_GUN` | bool | — | Включить сервис `mailgun` |
| `ENABLE_SMTP` | bool | — | Включить сервис `smtp` |
| `ENABLE_WORKSPACE_API_DB` | bool | — | Включить сервис `workspace_api_db` |
| `ENABLE_CROSS_SECTION_API_DB` | bool | — | Включить сервис `cross-section-api-db` |
| `BIM_API_DEBUG` | bool | — | Флаг debug для BIM API (также пробрасывается в под, см. ниже) |
| `COMPARISONS_API_DEBUG` | string | — | Флаг debug для Comparisons API (также пробрасывается в под) |
| `INTERNAL_PDM_URL` | string | — | Внутренний URL PDM |
| `EXTERNAL_PDM_URL` | string | — | Внешний URL PDM |
| `INTERNAL_FILESTREAM_URL` | string | — | Внутренний URL filestream |
| `EXTERNAL_FILESTREAM_URL` | string | — | Внешний URL filestream |
| `INTERNAL_REMARK_URL` | string | — | Внутренний URL remarks |
| `EXTERNAL_REMARK_URL` | string | — | Внешний URL remarks |
| `DJANGO_HOST` | string | — | URL Django-хоста (ЛК) |
| `INTERNAL_WORKSPACE_URL` | string | — | Внутренний URL workspaces |
| `EXTERNAL_WORKSPACE_URL` | string | — | Внешний URL workspaces |
### Пулинг (`Pooling`)
| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `MAX_WORKFLOWS_LIMIT` | uint64 | — (0) | Лимит одновременно обрабатываемых workflow при выборке |
| `MAX_RUNNING_JOBS` | int64 | `200` | Максимум одновременно выполняющихся Job'ов |
### Workflow (`Workflows`)
| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `DEFAULT_GET_SINCE_LAST_HOURS` | uint64 | `168` | Глубина выборки задач в часах (нужно для FIFO; 168 ч = 7 дней) |
| `WORKFLOW_PRIORITY` | enum (`default`/`high`/`low`) | `default` | Приоритет обрабатываемых workflow (задаёт «роль» инстанса) |
### Безопасность (`Security`)
| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `ENABLE_RUNASUSER` | bool | `false` | Запускать контейнеры задач под фиксированным UID |
| `USER_RUNASUSER` | int64 | `1000` | UID для `runAsUser` |
### Переменные, читаемые через `os.Getenv` и пробрасываемые в под'ы задач
Эти переменные **не входят** в структуру `Config` и **не потребляются** самим engine. Они читаются напрямую в `pkg/kube_services/services.go` и добавляются как env в контейнер запускаемой задачи (Job), когда включён соответствующий `ENABLE_*`-флаг. Тип — всегда строка (передаётся «как есть»).
| Переменная | Куда прокидывается (условие) | Назначение |
| --- | --- | --- |
| `BIM_API_DB` | сервис `bim_api_db` (при `ENABLE_BIM_API_DB`) | Путь к JSON-конфигу БД BIM API |
| `BIM_API_DEBUG` | сервис `bim_api_db` | Флаг debug |
| `BIM_API_CH` | сервис `bim_api_ch` (при `ENABLE_BIM_API_CH`) | Путь к JSON-конфигу ClickHouse |
| `BIM_API_CH_DEBUG` | сервис `bim_api_ch` | Флаг debug |
| `BIM_API_V2_DB` | сервис `bim_api_v2_db` (при `ENABLE_BIM_API_V2_DB`) — в под прокидывается под именем `BIM_API_DB` | Путь к JSON-конфигу БД BIM API v2 |
| `BIM_API_V2_DEBUG` | сервис `bim_api_v2_db` | Флаг debug |
| `BIM_API_V2_DB_2` | сервис `bim_api_v2_db_2` — в под как `BIM_API_DB_2` | Путь к JSON-конфигу 2-й БД BIM v2 |
| `BIM_API_V2_DB_3` | сервис `bim_api_v2_db_3` — в под как `BIM_API_DB_3` | Путь к JSON-конфигу 3-й БД BIM v2 |
| `BIM_API_V2_DB_4` | сервис `bim_api_v2_db_4` — в под как `BIM_API_DB_4` | Путь к JSON-конфигу 4-й БД BIM v2 |
| `COMPARISONS_API_DB` | сервис `comparison-api-db` (при `ENABLE_COMPARISONS_API_DB`) | Путь к JSON-конфигу БД Comparisons |
| `COMPARISONS_API_DEBUG` | сервис `comparison-api-db` | Флаг debug |
| `ISSUE_API_DB` | сервис `issues-api-db` (при `ENABLE_ISSUE_API_DB`) | Путь к JSON-конфигу БД Issues |
| `ISSUE_API_DEBUG` | сервис `issues-api-db` | Флаг debug |
| `RESOURCES_API_INTERNAL_HOST` | сервис `resources-api` (при `ENABLE_RESOURCES_API`) | Внутренний хост Resources API |
| `SMTP` | сервис `smtp` (при `ENABLE_SMTP`) — в под как `SMTP_CONFIG_PATH` | Путь к JSON-конфигу SMTP |
| `PDM_API_DB` | сервис `pdm_api_db` (при `ENABLE_PDM_API_DB`) | Путь к JSON-конфигу БД PDM |
| `PDM_API_DEBUG` | сервис `pdm_api_db` | Флаг debug |
| `WORKSPACE_API_DB` | сервис `workspace_api_db` (при `ENABLE_WORKSPACE_API_DB`) | Путь к JSON-конфигу БД Workspace |
| `WORKSPACE_API_DEBUG` | сервис `workspace_api_db` | Флаг debug |
| `CROSS_SECTION_API_DB` | сервис `cross-section-api-db` (при `ENABLE_CROSS_SECTION_API_DB`) | Путь к JSON-конфигу БД Cross-section |
| `CROSS_SECTION_API_DEBUG` | сервис `cross-section-api-db` | Флаг debug |
| `WORKFLOWS_SENTRY_DSN` | сервис `Default` (всегда) | Sentry DSN для подов задач |
| `WORKFLOWS_SENTRY_DEBUG` | сервис `Default` (всегда) | Флаг debug Sentry |
| `ENVIRONMENT` | сервис `Default` (всегда) | Имя окружения для подов задач |
> Пути `BIM_API_V2_DB_2/3/4`, `MAILGUN`, `SMTP` и т.п. задаются в Helm-чарте (`.helm/values.yaml`) — в `config.env` присутствуют не все из них.
## Переменные инфраструктуры/сборки
| Переменная | Где | Назначение |
| --- | --- | --- |
| `CGO_ENABLED=0`, `GOOS=linux`, `GOARCH=amd64` | Dockerfile (build stage) | Статическая сборка бинаря под Linux/amd64 |
| `CI_COMMIT_SHORT_SHA` | `.gitlab-ci.yml` → build-arg | Прокидывается в сборку образа |
| `SERVICE_NAME=workflows-engine` | `.gitlab-ci.yml` | Имя сервиса/чарта в CI |
| `DOCKERFILE_PATH=Dockerfile` | `.gitlab-ci.yml` | Путь к Dockerfile |
| `BUILD_ARGS` | `.gitlab-ci.yml` | Аргументы сборки образа |
| `CI_TRIGGER_SOURCE=app` | `.gitlab-ci.yml` | Источник триггера пайплайна |
| `IMAGE_NAME`, `CI_COMMIT_SHA`, `CI_PROJECT_URL`, `CI_JOB_URL`, `CI_PROJECT_NAMESPACE` | `.gitlab-ci.yml``HELM_SET_ARGS` | Метаданные деплоя, пробрасываются в universal-chart |
Сборка/деплой наследуются из внешних CI-шаблонов проекта `generic/common-ci` (`universal-pipeline.yaml`, `common-security-scan.yaml`). Юнит-тесты: стадия `test`, образ `golang:1.20`, команда `make unit-tests`.
## Переменные из Helm-чарта
Чарт (`.helm/values.yaml`) построен на `universal-chart`; секреты монтируются как env (`secretEnvs`) и как volume'ы. Ниже — маппинг секретных env (общий для `backend` и `backend-high-priority`). Имя секрета зависит от окружения (`_default` / `stage` / `preprod` / `production`).
| Переменная | Секрет (secret_name) | Ключ (secret_key) |
| --- | --- | --- |
| `POSTGRES_ADDRESS` | `ya-pg-secret` (stage: `processing-postgresql-secret`) | `host` |
| `POSTGRES_PORT` | `ya-pg-secret` (stage: `processing-postgresql-secret`) | `port` |
| `POSTGRES_DB` | `ya-pg-secret` (stage: `processing-postgresql-secret`) | `database` |
| `POSTGRES_USER` | `ya-pg-secret` (stage: `processing-postgresql-secret`) | `username` |
| `POSTGRES_PASSWORD` | `ya-pg-secret` (stage: `processing-postgresql-secret`) | `password` |
| `RABBITMQ_USER` | `rabbitmq-secret` | `username` |
| `RABBITMQ_PASS` | `rabbitmq-secret` | `password` |
| `YC-PG-CERTIFICATE` | `yc-pg-certificate` (stage: `processing-postgresql-secret`) | `certificate` (stage: `ca.crt`, preprod/prod: `certificate`) |
Секреты, монтируемые как volume'ы (файлы JSON-конфигов внешних БД и т.п.):
| Volume / секрет | mountPath |
| --- | --- |
| `yc-s3` | `/etc/sarex/yc-s3` |
| `bim-api-db` | `/etc/sarex` |
| `bim-api-v2-db-2` | `/etc/sarex/second-bim-bd` |
| `bim-api-v2-db-3` | `/etc/sarex/third-bim-bd` |
| `bim-api-v2-db-4` | `/etc/sarex/fourth-bim-bd` |
| `comparison-api-db` | `/etc/comparisons` |
| `pdm-api-db` | `/etc/pdm` |
| `ws-api-db` | `/etc/ws` |
| `mailgun-secret` | `/etc/mailgun-secret` |
| `smtp-secret` | `/etc/smtp-secret` |
| `issues-api-db` | `/etc/issues` |
| `cross-section-api-db` | `/etc/cross_section` |
| `tmp-volume` (emptyDir) | `/tmp` |
Прочие значимые переменные окружения задаются в `.helm/values.yaml` секцией `envs` для каждого сервиса (значения зависят от окружения `_default/stage/preprod/production`) — в т.ч. пути к JSON-конфигам (`BIM_API_DB`, `PDM_API_DB`, …), URL'ы сервисов, `POD_NAME=$(K8S_POD_NAME)`, `WORKFLOW_PRIORITY` (`low` для `backend`, `high` для `backend-high-priority`). Также в чарте описан `meshConfig` (Istio) — включён только для production.
## Переменные в CI
Определяются в `workflow.rules` файла `.gitlab-ci.yml` по ветке/тегу:
| Триггер | STAND | NAMESPACE | universal-chart env | CHART_VERSION | K8S_HUSTLER_BRANCH |
| --- | --- | --- | --- | --- | --- |
| ветка `stage` | `stage` | `platform` | `stage` | `0.0.1-stage` | `universal-chart-stage` |
| ветка `master` | `preprod` | `processing-preprod` | `preprod` | `0.0.1-preprod` | `universal-chart-preprod` |
| тег (`CI_COMMIT_TAG`) | `production` | `processing-prod` | `production` | `0.0.1-prod` | `universal-chart-production` |
| Merge Request | — (сборка образа выключена: `ENABLE_BUILD_IMAGE=false`) | — | — | — | — |
`RELEASE_NAME` во всех случаях — `workflows-engine`. Для каждого стенда деплоятся оба сервиса: `backend` и `backend-high-priority`.
## Замечания и потенциальные проблемы
1. **Нет HTTP REST API, но `API_ADDRESS` присутствует.** Переменная `API_ADDRESS=0.0.0.0:8080` есть в `config.env` и в Helm (`envs`), но **не читается ни одной строкой Go-кода**. Реальный HTTP-сервер — только `net/http/pprof` на `:8081` (`cmd/engine/main.go`). В Helm у сервисов `service.enabled: false`, liveness/readiness-пробы выключены. Переменную стоит либо удалить, либо реализовать сервер. По этой причине `openapi.yaml` для сервиса не создаётся.
2. **Дубликаты в `config.env`:**
- `ENABLE_BIM_API_V2_DB=1` указана дважды (строки 18 и 19);
- `JOBS_NAMESPACE` задаётся дважды с разными значениями: `processing-stage` и `processing-testing` — побеждает последнее;
- `POD_NAME` задаётся дважды: `fieldRef(v1:metadata.name)` и `workflows-backend-869584d795-b7p2b` — второе значение это «замороженное» имя конкретного пода, что явно ошибочно для шаблона.
3. **Хардкод локальных путей разработчика в `config.env`:**
- `S3_SERVICE_ACCOUNT=/Users/khannanov/sarex/yc-s3-service-account.json`;
- `KUBE_CONFIG=/Users/khannanov/.kube/config`.
Эти пути специфичны для машины конкретного разработчика и не должны попадать в общий конфиг (в Helm `S3_SERVICE_ACCOUNT` корректно указывает на `/etc/sarex/yc-s3/...`).
4. **Переменные из `config.env`/Helm, которые не читаются кодом `engine` вообще** (кандидаты на удаление либо потребляются исключительно другими компонентами): `API_ADDRESS`, `CONTROL_PLANE_PERIOD`, `ENABLE_GOOGLE_STORAGE`, `GOOGLE_STORAGE_BUCKET`, `GOOGLE_STORAGE_PROJECT`, `ENABLE_SRX_TMP`, `MAX_TASKS_IN_PERIOD`, `ENABLE_PDM_DB`, `POD_NAME`. Ни `Getenv`, ни struct-тега для них нет.
5. **`config.env` частично устарел относительно `config/config.go` и Helm.** Ряд переменных, реально используемых кодом/чартом, в `config.env` отсутствует (`WORKFLOW_PRIORITY`, `DEFAULT_TOLERATION_*`, `DEFAULT_NODE_SELECTOR_*`, `ENABLE_ISSUE_API_DB`, `ENABLE_RESOURCES_API`, `ENABLE_WORKSPACE_API_DB`, `ENABLE_CROSS_SECTION_API_DB`, `RESOURCES_API_INTERNAL_HOST`, `WORKFLOWS_SENTRY_DSN`, пути `*_API_DB` для issues/ws/cross_section и т.д.). Источником истины следует считать `config/config.go` + `.helm/values.yaml`, а не `config.env`.
6. **Расхождение `env-default` и реальных значений.** У ряда флагов (`ENABLE_S3_STORAGE`, `ENABLE_TOLERATION`, `CPU_COUNT`, воркеры и др.) в коде нет `env-default`, поэтому при отсутствии переменной поле останется нулевым (`0`/`false`/`""`) — сервис молча стартует с «пустой» конфигурацией планирования. Значения обязательно должны задаваться через окружение (Helm).
7. **`DJANGO_BASIC_AUTH` / `COMPARISONS_API_DEBUG` / `BIM_API_DEBUG`** объявлены в структуре конфига, но фактически в бизнес-логике engine не задействованы (debug-флаги повторно читаются через `os.Getenv` и прокидываются в поды; `DJANGO_BASIC_AUTH` не используется — в под задачи попадает хардкод-путь `DJANGO_BASIC_AUTH_PATH=/etc/sarex/django-auth.json`).
8. **`RABBITMQ_CREATE_TOPIC`** присутствует в `config.env`, но в конфиге RabbitMQ такого поля нет (используется `RABBITMQ_CREATE_ROUTING_KEY`) — переменная не читается.
## Минимальный набор для локального запуска
Для локального старта достаточно поднять PostgreSQL и указать доступ к нему; исполнители и внешние интеграции можно выключить.
```env
# Логирование
LOG_LEVEL=debug
# PostgreSQL (обязательно — engine сразу подключается к БД)
POSTGRES_ADDRESS=localhost
POSTGRES_PORT=5432
POSTGRES_DB=processing_db
POSTGRES_USER=user
POSTGRES_PASSWORD=password
POSTGRES_POOL_SIZE=5
POSTGRES_SSL_USE=false
ENABLE_SQL_QUERY=true
# Исполнители: выключаем AMQP; для Kubernetes нужен доступ к кластеру
ENABLE_AMQP_EXECUTOR=0
ENABLE_KUBERNETES_EXECUTOR=1
KUBE_CONFIG=/path/to/your/.kube/config # если пусто — используется in-cluster
KUBE_CONTEXT=your-context
JOBS_NAMESPACE=processing-testing
# Воркеры
COUNT_RUNNING_WORKERS=1
COUNT_CANCELING_WORKERS=1
COUNT_HANDLE_JOB_WORKERS=1
# Пулинг / выборка
MAX_WORKFLOWS_LIMIT=10
MAX_RUNNING_JOBS=10
DEFAULT_GET_SINCE_LAST_HOURS=168
WORKFLOW_PRIORITY=default
# Дефолты планирования подов (иначе будут пустыми)
DEFAULT_IMAGE_PULL_POLICY=IfNotPresent
DEFAULT_CPU_REQUESTS=100m
DEFAULT_MEMORY_REQUESTS=64Mi
# Хранилища/внешние БД можно отключить для минимального запуска
ENABLE_S3_STORAGE=0
ENABLE_S3V2_STORAGE=0
ENABLE_PDM_STORAGE=0
ENABLE_URL_STORAGE=0
ENABLE_LOCAL=0
ENABLE_BIM_API_DB=0
ENABLE_BIM_API_CH=0
ENABLE_BIM_API_V2_DB=0
ENABLE_PDM_API_DB=0
ENABLE_COMPARISONS_API_DB=0
ENABLE_ISSUE_API_DB=0
ENABLE_RESOURCES_API=0
ENABLE_MAIL_GUN=0
ENABLE_SMTP=0
ENABLE_WORKSPACE_API_DB=0
ENABLE_CROSS_SECTION_API_DB=0
ENABLE_TOLERATION=0
```
Запуск: `go run ./cmd/engine`. Если Kubernetes-исполнитель не нужен вовсе — установите `ENABLE_KUBERNETES_EXECUTOR=0` (тогда `KUBE_*`/`JOBS_NAMESPACE` не требуются), но учтите, что без единого включённого исполнителя сервис не будет запускать задачи. Профилирование доступно на `http://localhost:8081/debug/pprof/`.