# Конфигурация проекта notes-backend Документ описывает все переменные окружения и способы конфигурирования сервиса. ## Способы конфигурирования Сервис настраивается **только через переменные окружения**. Разбор выполняется в `src/app/config.py` через библиотеку [`pydantic`](https://docs.pydantic.dev/) (`pydantic.BaseSettings`, pydantic v1). Конфигурация разбита на несколько классов настроек, каждый со своим префиксом (`Config.env_prefix`): - `PostgresSettings` — префикс `PG_`; - `DjangoSettings` — префикс `DJANGO_`; - `Documentations` — префикс `DOCUMENTATIONS_`; - `WorkflowSettings` — префикс `WORKFLOW_`; - `AttachmentSettings` — префикс `ATTACHMENT_`; - `LoggerSettings` — префикс `LOG_`; - корневой `Settings` — **без префикса** (поля читаются по имени в верхнем регистре, напр. `BASE_HOST`, `FAAS_SERVICE`). Каждый вложенный класс настроек инстанцируется отдельно и читает свои переменные из окружения по своему префиксу. Отдельного конфиг-файла (yaml/toml) у приложения нет. Источники переменных по способам запуска: | Способ запуска | Откуда берутся переменные | | --- | --- | | Локально (uvicorn/gunicorn) | Переменные окружения процесса. Приложение **не загружает `.env` автоматически** (в `config.py` нет `env_file`/`python-dotenv`) — переменные нужно экспортировать самому | | Локально (контейнеры) | `docker-compose.yml`: блок `environment` для сервиса `notes` (`PG_HOST`, `PG_DB`, `PG_LOGIN`, `PG_PASSWORD`, `DJANGO_USE`, `TIMEOUT`) | | Kubernetes (Helm) | `.helm/values.yaml`: блоки `envs` (обычные значения) и `secretEnvs` (значения из k8s-секретов) чарта `universal-chart` | | CI/CD (GitLab) | `.gitlab-ci.yml`: переменные пайплайна (`workflow.rules`) — выбор окружения по ветке/тегу | Порядок запуска в контейнере (`entrypoint.sh`): сначала выполняются миграции (`alembic upgrade head`), затем стартует gunicorn с воркерами `uvicorn.workers.UvicornWorker` на `0.0.0.0:8000` с таймаутом `$TIMEOUT`. ## Переменные приложения Дефолт `—` означает, что явного значения по умолчанию нет (пустая строка/обязательно задать для реального окружения). ### App / корневой `Settings` (без префикса) | Переменная | Тип | Значение по умолчанию | Назначение | | --- | --- | --- | --- | | `BASE_HOST` | string | `https://lk.sarex.io` | Внешний базовый URL сервиса | | `API_PREFIX` | string | `/api/v1` | Префикс публичного API | | `DEBUG` | bool | `False` | Режим отладки. Также влияет на `PostgresSettings` (см. ниже) и включает `ProfilingSqlQueryMiddleware` | | `FAAS_SERVICE` | string | `https://stage-api.sarex.io/lambdas` | URL сервиса лямбд/FaaS | | `WORKSPACE_URL` | string | `https://stage-api.sarex.io/workspaces/api/v1` | URL сервиса рабочих областей (для `SYNC_RESOURCE_ID`) | | `RESOURCE_URL` | string | `https://stage-api.sarex.io/resources/api/v1` | URL сервиса ресурсов (для `SYNC_RESOURCE_ID`) | | `SYNC_RESOURCE_ID` | bool | `False` | При `True` `resource_id` заметки вычисляется по workspace → target → resource | | `REGISTRY` | string | `cr.yandex/crp3ccidau046kdj8g9q/` | Реестр образов (используется вспомогательно) | | `ENABLE_ND` | bool | `False` | Подключить роутер `nd_service` (`/api/v1/nd/*`) | ### ND-сервис (без префикса) | Переменная | Тип | Значение по умолчанию | Назначение | | --- | --- | --- | --- | | `ND_JWT_ENABLE` | bool | `False` | Включить проверку JWT (`JWTBearer`) на части эндпоинтов НД | | `ND_JWT_SECRET` | string | `""` | Секрет для подписи/проверки JWT | | `ND_JWT_ALGORITHM` | string | `HS256` | Алгоритм JWT | | `ND_ACCESS_TOKEN_EXPIRE_DAYS` | int | `30` | Срок жизни токена НД (дни) | ### Database (`PG_*`) | Переменная | Тип | Значение по умолчанию | Назначение | | --- | --- | --- | --- | | `PG_LOGIN` | string | `""` | Пользователь PostgreSQL | | `PG_PASSWORD` | string | `""` | Пароль пользователя | | `PG_DB` | string | `""` | Имя базы данных | | `PG_HOST` | string | `""` | Хост PostgreSQL | | `PG_PORT` | string | `5432` | Порт PostgreSQL | | `PG_SSL_MODE` | string | `disable` | Поле `ssl_mode` настроек (см. замечание ниже — фактически подключение всегда `verify-full`) | | `DEBUG` | bool | `False` | Через `Field(env='DEBUG')`. При `True` хост БД принудительно `localhost:6432` (pgbouncer) | > Итоговый DSN собирается в `PostgresSettings.url` как `postgresql://:@:/`. ### Django / sarex-backend (`DJANGO_*`) Клиент к основному backend (Django). Используется middleware `DjangoUserMiddleware` для аутентификации пользователя (запрос `/client/settings/`). | Переменная | Тип | Значение по умолчанию | Назначение | | --- | --- | --- | --- | | `DJANGO_USE` | bool | `True` | При `False` аутентификация через Django отключается, используется тестовый пользователь (`is_admin=True`) | | `DJANGO_HOST` | string | `http://localhost:8000` | Базовый хост Django (к нему добавляется `/api`) | | `DJANGO_TIMEOUT` | int | `10` | Таймаут HTTP-клиента (сек) | | `DJANGO_TOKEN` | string | `token` | Токен для служебных (sync) запросов | ### Documentations (`DOCUMENTATIONS_*`) | Переменная | Тип | Значение по умолчанию | Назначение | | --- | --- | --- | --- | | `DOCUMENTATIONS_HOST` | string | `https://stage-api.sarex.io/documentations/api/v1` | URL сервиса документации | ### Workflows (`WORKFLOW_*`) | Переменная | Тип | Значение по умолчанию | Назначение | | --- | --- | --- | --- | | `WORKFLOW_HOST` | string | `https://stage-api.sarex.io/workflows/api/v1` | URL сервиса обработки процессов | | `WORKFLOW_TAG` | string | `dev` | Тег/канал workflow (`dev`/`stable`) | | `WORKFLOW_TIMEOUT` | int | `30` | Таймаут HTTP-клиента (сек) | ### Attachments (`ATTACHMENT_*`) | Переменная | Тип | Значение по умолчанию | Назначение | | --- | --- | --- | --- | | `ATTACHMENT_HOST` | string | `http://attachments-service.attachments-stage.svc.cluster.local:80/api/v1` | URL сервиса вложений | | `ATTACHMENT_TIMEOUT` | int | `30` | Таймаут HTTP-клиента (сек) | ### Logger (`LOG_*`) | Переменная | Тип | Значение по умолчанию | Назначение | | --- | --- | --- | --- | | `LOG_LEVEL` | string | `INFO` | Уровень логирования (`DEBUG`/`INFO`/…); при неизвестном значении используется `INFO` | | `LOG_FORMAT` | string | `[%(asctime)s] [%(levelname)s] [%(filename)s]: %(message)s` | Формат сообщений лога | ## Переменные инфраструктуры, сборки и вспомогательных утилит Не читаются кодом приложения, но участвуют в запуске/сборке/деплое. | Переменная | Где используется | Назначение | | --- | --- | --- | | `TIMEOUT` | `docker-compose.yml`, `.helm/values.yaml`, `entrypoint.sh` | Таймаут воркеров gunicorn (`--timeout`) | | `POSTGRES_USER` / `POSTGRES_PASSWORD` / `POSTGRES_DB` | `docker-compose.yml` (сервис `database`) | Параметры локального контейнера Postgres | | `PGADMIN_DEFAULT_EMAIL` / `PGADMIN_DEFAULT_PASSWORD` | `docker-compose.yml` (сервис `pgadmin`) | Учётные данные pgAdmin для локальной разработки | | `NPM_NEXUS_TOKEN` | (для фронтенда) | Токен приватного npm-реестра — здесь не используется | ## Переменные из Helm-чарта (`.helm/values.yaml`) Чарт — `universal-chart` (зависимость в `.helm/Chart.yaml`). Обычные значения задаются в блоке `services.main.envs` и различаются по окружениям (`_default`/`stage`/`preprod`/`production`): | Переменная | `_default` (stage) | `preprod` | `production` | | --- | --- | --- | --- | | `PG_SSL_MODE` | `verify-full` | — | — | | `PG_PORT` | `6432` | — | — | | `DJANGO_HOST` | `https://stage.sarex.io` | `https://lk.preprod.sarex.io` | `https://lk.sarex.io` | | `BASE_HOST` | `https://stage-api.sarex.io/notes` | `https://api.preprod.sarex.io/notes` | `https://api.sarex.io/notes` | | `TIMEOUT` | `120` | — | — | | `FAAS_SERVICE` | `https://stage-api.sarex.io/lambdas` | `https://api.preprod.sarex.io/lambdas` | `https://api.sarex.io/lambdas` | | `WORKSPACE_URL` | `https://stage-api.sarex.io/workspaces/api/v1` | `https://api.preprod.sarex.io/workspaces/api/v1` | `https://api.sarex.io/workspaces/api/v1` | | `WORKFLOW_HOST` | `https://stage-api.sarex.io/workflows/api/v1` | `https://api.preprod.sarex.io/workflows/api/v1` | `https://api.sarex.io/workflows/api/v1` | | `WORKFLOW_TAG` | `dev` | `stable` | `stable` | | `RESOURCE_URL` | `https://stage-api.sarex.io/resources/api/v1` | `https://api.preprod.sarex.io/resources/api/v1` | `https://api.sarex.io/resources/api/v1` | | `SYNC_RESOURCE_ID` | `0` | — | — | | `ENABLE_ND` | `1` | `0` | `0` | | `ATTACHMENT_HOST` | `…attachments-stage…` | `…attachments-preprod…` | `…attachments-prod…` | Значения из секретов (блок `secretEnvs`, монтируются как env через `secretKeyRef`): | Переменная | Секрет (`secretName`, stage) | Ключ (`secretKey`) | | --- | --- | --- | | `PG_DB` | `notes-postgresql-secret` | `database` | | `PG_LOGIN` | `notes-postgresql-secret` | `username` | | `PG_PASSWORD` | `notes-postgresql-secret` | `password` | | `PG_HOST` | `notes-postgresql-secret` | `host` | | `DJANGO_TOKEN` | `django-secret` | `token` | Прочие значения чарта (не переменные приложения): `deployment.*` (имя, порт `8000`, реплики, ресурсы, probes отключены), `image.*`, `service.*` (`notes-backend-service`, в production — `backend-service`), `imagePullSecrets` (`dockerhub`), `ingress.enabled: false`. ## Переменные в CI (`.gitlab-ci.yml`) Пайплайн подключает общие шаблоны из `generic/common-ci` (`common-security-scan.yaml`, `universal-pipeline.yaml`) и переключает окружение по ветке/тегу через `workflow.rules`: | Условие | STAND | NAMESPACE | CHART_VERSION | | --- | --- | --- | --- | | ветка `stage` | `stage` | `aero` | `0.0.1-stage` | | ветка `master` | `preprod` | `notes-preprod` | `0.0.1-preprod` | | тег (`CI_COMMIT_TAG`) | `production` | `notes-prod` | `0.0.1-prod` | Ключевые переменные: `SERVICE_NAME=notes-backend`, `DOCKERFILE_PATH`, `RELEASE_NAME`, `CHART_NAME`, `HELM_SET_ARGS` (проброс образа/окружения в `universal-chart`). Джобы `linter` (flake8), `typechecker` (mypy), `rest-api` (docker-compose + newman/postman) выполняются на MR/ветках/тегах. ## Замечания и потенциальные проблемы - **SSL к БД всегда `verify-full`.** Поле `PG_SSL_MODE` (по умолчанию `disable`) в код подключения не попадает: и `PostgresSettings.create_session`, и `DBSessionMiddleware` жёстко передают `connect_args={'sslmode': "verify-full"}`. CA-сертификат монтируется из образа: `Dockerfile` копирует `yandex_pg.pem` → `/root/.postgresql/root.crt`. - **`DEBUG` — общая переменная.** Она читается и корневым `Settings.debug`, и `PostgresSettings.debug` (`Field(env='DEBUG')`). При `DEBUG=true` хост БД принудительно становится `localhost:6432`, а также включается `ProfilingSqlQueryMiddleware`. - **Приложение не загружает `.env` автоматически** — переменные нужно экспортировать в окружение (или задавать через `--env`/compose/helm). - **Аутентификация.** При `DJANGO_USE=true` каждый публичный запрос (кроме путей с `/nd`) проверяется через Django `/client/settings/` по заголовку `Authorization` (опционально `Identity` для Zitadel). При `DJANGO_USE=false` подставляется тестовый администратор — использовать только локально. - **Роутер НД включается флагом `ENABLE_ND`.** На stage он включён (`1`), на preprod/production выключен (`0`). - Значение `SYNC_RESOURCE_ID` требует доступности `WORKSPACE_URL` и `RESOURCE_URL`; клиент к ним создаётся с `verify=False`. ## Минимальный набор для локального запуска Postgres и pgAdmin поднимаются через `docker-compose up -d database pgadmin`. Минимально необходимо задать: - `PG_LOGIN`, `PG_PASSWORD`, `PG_DB`, `PG_HOST`, `PG_PORT` - `DJANGO_USE=false` (чтобы не требовать реальный Django-токен) - при `ENABLE_ND=true` — `ND_JWT_*` при необходимости проверки токена Остальные значения имеют рабочие дефолты (см. `.env.example`).