172 lines
14 KiB
Markdown
172 lines
14 KiB
Markdown
# Конфигурация проекта checklists-backend
|
||
|
||
Документ описывает все переменные окружения и способы конфигурирования сервиса.
|
||
|
||
## Способы конфигурирования
|
||
|
||
Сервис настраивается **только через переменные окружения**. Разбор выполняется в `src/config.py` через библиотеку [`pydantic-settings`](https://docs.pydantic.dev/latest/concepts/pydantic_settings/).
|
||
|
||
В отличие от единого класса настроек, конфигурация разбита на несколько независимых классов `BaseSettings`, у каждого — **свой** `env_prefix` (плоские имена, без вложенного разделителя):
|
||
|
||
| Класс | `env_prefix` | Раздел |
|
||
| --- | --- | --- |
|
||
| `Config` | *(нет префикса)* | `debug` |
|
||
| `HTTPAppConfig` | `HTTP_APP_` | Параметры HTTP-приложения/uvicorn |
|
||
| `DatabaseConfig` | `DATABASE_` | Подключение к PostgreSQL |
|
||
| `OTELConfig` | `OTEL_` | Трейсинг/логи OpenTelemetry |
|
||
| `JWTAuthConfig` | `JWT_AUTH_` | Аутентификация по JWT |
|
||
|
||
Подклассы подключаются к корневому `Config` как поля со значениями по умолчанию (`http_app`, `database`, `otel`, `jwt_auth`) и читают окружение в момент импорта. Отдельного конфиг-файла (yaml/toml) у приложения нет.
|
||
|
||
Особенности:
|
||
|
||
- **`.env` не загружается автоматически** — в `config.py` не задан `env_file`, зависимости `python-dotenv` нет. Файл `.env.template` — это шаблон; переменные нужно экспортировать в окружение самому (напр. `set -a && . ./.env && set +a`) либо задавать через `--env`/манифесты k8s.
|
||
- Помимо переменных приложения, для запуска нужны две инфраструктурные переменные Piccolo: `PYTHONPATH=src` и `PICCOLO_CONF=db.config` (заданы в `.env.template` и в `Dockerfile`).
|
||
|
||
Источники переменных по способам запуска:
|
||
|
||
| Способ запуска | Откуда берутся переменные |
|
||
| --- | --- |
|
||
| Локально (`make run`) | Переменные окружения процесса. `.env.template` — шаблон, приложение его **не подхватывает** автоматически |
|
||
| Контейнер | `docker/http/Dockerfile` задаёт `PYTHONPATH`/`PICCOLO_CONF`; прочие переменные пробрасываются при запуске |
|
||
| Kubernetes (Helm) | `.helm/values.yaml`: блоки `envs` (обычные значения) и `secretEnvs` (значения из k8s-секретов) чарта `universal-chart` |
|
||
| CI/CD (GitLab) | `.gitlab-ci.yml`: переменные пайплайна (`workflow.rules`) и `HELM_SET_ARGS` |
|
||
|
||
Способы запуска (`Makefile`):
|
||
|
||
| Команда | Точка входа | Назначение |
|
||
| --- | --- | --- |
|
||
| `make run` | `src/cmd/http/main.py` → `uvicorn` (factory `app.http:create_app`) | HTTP API |
|
||
| `make migrate` | `piccolo migrations forwards all` | Применение миграций БД |
|
||
| `make migrations` | `piccolo migrations new checklists --auto` | Генерация новой миграции |
|
||
| `make format` / `make format-check` | `ruff` | Форматирование/линт |
|
||
|
||
Порядок запуска в контейнере (`docker/http/entrypoint.sh`): сначала выполняются миграции (`piccolo migrations forwards all`), затем стартует приложение (`src/cmd/http/main.py`). Uvicorn запускается в режиме фабрики; `reload` включается при `DEBUG=true`, число воркеров — из `HTTP_APP_WORKERS`.
|
||
|
||
## Переменные приложения
|
||
|
||
В столбце «Переменная» указано полное имя (префикс + поле). Дефолт `—` означает, что значение обязательно.
|
||
|
||
### App (`Config`)
|
||
|
||
| Переменная | Тип | Значение по умолчанию | Назначение |
|
||
| --- | --- | --- | --- |
|
||
| `DEBUG` | bool | `True` | Режим отладки. Влияет на `reload` uvicorn, логирование SQL-запросов Piccolo (`log_queries`/`log_responses`), а также на `production`-флаг и `debug` piccolo-admin |
|
||
|
||
### HTTP-приложение (`HTTP_APP_*`)
|
||
|
||
| Переменная | Тип | Значение по умолчанию | Назначение |
|
||
| --- | --- | --- | --- |
|
||
| `HTTP_APP_HOST` | string | `0.0.0.0` | Адрес прослушивания |
|
||
| `HTTP_APP_PORT` | int | `8000` | Порт |
|
||
| `HTTP_APP_ROOT_PATH` | string | `""` | Root path (префикс за реверс-прокси; в k8s — `/checklists`) |
|
||
| `HTTP_APP_WORKERS` | int | `1` | Число воркеров uvicorn |
|
||
| `HTTP_APP_ADMIN_ENABLE` | bool | `True` | Монтировать ли piccolo-admin по пути `/admin/` |
|
||
|
||
### Database (`DATABASE_*`)
|
||
|
||
| Переменная | Тип | Значение по умолчанию | Назначение |
|
||
| --- | --- | --- | --- |
|
||
| `DATABASE_HOST` | string | `postgres` | Хост PostgreSQL |
|
||
| `DATABASE_PORT` | int | `5432` | Порт PostgreSQL |
|
||
| `DATABASE_NAME` | string | `postgres` | Имя базы данных |
|
||
| `DATABASE_USER` | string | `postgres` | Пользователь БД |
|
||
| `DATABASE_PASSWORD` | string | `postgres` | Пароль пользователя БД |
|
||
|
||
Подключение собирается в `src/db/config.py` (`PostgresEngine`). SSL-параметров в настройках нет; в prod TLS обеспечивается на уровне подключения/CA-сертификата (см. `docker/http/ca.crt`).
|
||
|
||
### OpenTelemetry (`OTEL_*`)
|
||
|
||
| Переменная | Тип | Значение по умолчанию | Назначение |
|
||
| --- | --- | --- | --- |
|
||
| `OTEL_ENABLE` | bool | `False` | Включить трейсинг/логи OTEL. При `True` подключаются `fastapi-otel-tools` и инструментирование FastAPI |
|
||
| `OTEL_URL` | string | `http://signoz-otel-collector-external.signoz.svc.cluster.local:4317` | Адрес OTLP-коллектора |
|
||
| `OTEL_SERVICE_NAME` | string | `checklists-backend.checklists-stage` | Имя сервиса в трейсах |
|
||
| `OTEL_INSECURE` | bool | `True` | Небезопасное (без TLS) подключение к коллектору |
|
||
|
||
> При `OTEL_ENABLE=true` `access_log` uvicorn отключается (логи идут через OTEL-обработчик).
|
||
|
||
### Auth (`JWT_AUTH_*`)
|
||
|
||
| Переменная | Тип | Значение по умолчанию | Назначение |
|
||
| --- | --- | --- | --- |
|
||
| `JWT_AUTH_ENABLE` | bool | `False` | Включить `JWTAuthMiddleware`. При `False` middleware не подключается, и в контекст подставляется дефолтный пользователь (для локальной разработки) |
|
||
| `JWT_AUTH_PUBLIC_KEY` | string | `key` | Публичный RSA-ключ для JWT (алгоритм `RS512`) |
|
||
|
||
## Переменные инфраструктуры и сборки
|
||
|
||
Не читаются кодом приложения, но участвуют в запуске/сборке.
|
||
|
||
| Переменная | Где используется | Назначение |
|
||
| --- | --- | --- |
|
||
| `PYTHONPATH` | `.env.template`, `Dockerfile` | Путь к исходникам (`src`) |
|
||
| `PICCOLO_CONF` | `.env.template`, `Dockerfile` | Путь к конфигу Piccolo (`db.config`) |
|
||
| `SERVICE_NAME` | `.gitlab-ci.yml` | Имя сервиса (`checklists-backend`) |
|
||
| `DOCKERFILE_PATH` | `.gitlab-ci.yml` | Путь к Dockerfile (`./docker/http/Dockerfile`) |
|
||
| `IMAGE_NAME` | `.gitlab-ci.yml` (`HELM_SET_ARGS`) | Имя собираемого образа |
|
||
| `CHART_NAME` / `CHART_VERSION` / `RELEASE_NAME` | `.gitlab-ci.yml` | Параметры релиза Helm |
|
||
|
||
Базовый образ — `python:3.13-slim-bookworm`; менеджер зависимостей — `uv` (`uv sync --locked`). В образ добавляется CA-сертификат Yandex (`docker/http/ca.crt`).
|
||
|
||
## Переменные из Helm-чарта (`.helm/values.yaml`)
|
||
|
||
Сервис деплоится подключаемым чартом `universal-chart` (OCI-зависимость). Окружение выбирается ключом `universal-chart.global.env` (`stage`/`preprod`/`production`); для каждой переменной значение берётся из блока с ключом текущего окружения либо из `_default`.
|
||
|
||
Обычные значения (блок `envs`) переопределяют дефолты кода, в частности:
|
||
|
||
| Переменная | Значение в чарте |
|
||
| --- | --- |
|
||
| `HTTP_APP_ROOT_PATH` | `/checklists` |
|
||
| `HTTP_APP_WORKERS` | `3` |
|
||
| `HTTP_APP_ADMIN_ENABLE` | `true` |
|
||
| `DATABASE_PORT` | `6432` (PgBouncer) |
|
||
| `DATABASE_NAME` | `checklists_db` (stage), `checklists` (preprod/production) |
|
||
| `OTEL_ENABLE` | `true` |
|
||
| `OTEL_URL` | `http://otel-collector.opentelemetry-collector.svc.cluster.local:4317` |
|
||
| `OTEL_SERVICE_NAME` | `checklists-backend.proc` (stage), `…checklists-preprod`, `…checklists-prod` |
|
||
| `JWT_AUTH_ENABLE` | `true` |
|
||
| `DEBUG` | `false` |
|
||
|
||
Значения из секретов (блок `secretEnvs`, монтируются как env через `secretKeyRef`):
|
||
|
||
| Переменная | Секрет (`secretName`) | Ключ (`secretKey`) |
|
||
| --- | --- | --- |
|
||
| `DATABASE_USER` | `checklists-postgresql-secret` (stage) / `ya-pg-secret` (preprod, production) | `user` |
|
||
| `DATABASE_PASSWORD` | `checklists-postgresql-secret` / `ya-pg-secret` | `password` |
|
||
| `DATABASE_HOST` | `checklists-postgresql-secret` / `ya-pg-secret` | `host` |
|
||
| `JWT_AUTH_PUBLIC_KEY` | `jwt-secret` | `public-key` |
|
||
|
||
Прочие значения чарта (не переменные приложения): `deployment.*` (имя, реплики — 1 по умолчанию, 2 в production, ресурсы), `image.*`, `service.*` (ClusterIP, порт `80` → `8000`). Проверки `liveness`/`readiness` отключены.
|
||
|
||
## Переменные в CI (`.gitlab-ci.yml`)
|
||
|
||
Пайплайн подключает общие шаблоны из `generic/common-ci` (`universal-pipeline.yaml`, `common-security-scan.yaml`) и переключает окружение по ветке/тегу через `workflow.rules`:
|
||
|
||
| Условие | STAND | Namespace |
|
||
| --- | --- | --- |
|
||
| ветка `stage` | `stage` | `proc` |
|
||
| ветка `master` | `preprod` | `checklists-preprod` |
|
||
| тег (`CI_COMMIT_TAG`) | `production` | `checklists-prod` |
|
||
|
||
Ключевые переменные пайплайна: `SERVICE_NAME`, `DOCKERFILE_PATH`, `RELEASE_NAME`, `CHART_NAME`, `CHART_VERSION`, `K8S_HUSTLER_BRANCH`, `HELM_SET_ARGS` (проброс `image.name`, `global.env`, метаданных коммита). Job `lint` прогоняет `ruff check`/`ruff format --check` на образе `uv`.
|
||
|
||
## Замечания и потенциальные проблемы
|
||
|
||
- Приложение **не загружает `.env` автоматически** — переменные нужно экспортировать в окружение вручную либо задавать в манифестах.
|
||
- Аутентификация JWT в коде выполняет разбор токена с `options={"verify_signature": False}` в обоих режимах (sarex-backend и Zitadel) — подпись фактически не проверяется на уровне приложения, доверие обеспечивается сетевым слоем (Istio). При `JWT_AUTH_ENABLE=false` middleware не подключается и используется дефолтный пользователь из `entity/context.py`.
|
||
- Внутренние эндпоинты (`/internal/*`) аутентификации на уровне приложения не требуют.
|
||
- SSL-настроек подключения к БД в коде нет; в prod используется PgBouncer (`DATABASE_PORT=6432`) и CA-сертификат, вшитый в образ.
|
||
- Piccolo-admin доступен по `/admin/` при `HTTP_APP_ADMIN_ENABLE=true`; в режиме `DEBUG=false` он поднимается в `production`-режиме.
|
||
|
||
## Минимальный набор для локального запуска
|
||
|
||
Нужен доступный PostgreSQL. Помимо `PYTHONPATH=src` и `PICCOLO_CONF=db.config`, для запуска достаточно значений по умолчанию — обязательных переменных без дефолта нет. Практически стоит задать:
|
||
|
||
- `DEBUG` (`true` локально)
|
||
- `HTTP_APP_HOST`, `HTTP_APP_PORT`
|
||
- `DATABASE_HOST`, `DATABASE_PORT`, `DATABASE_NAME`, `DATABASE_USER`, `DATABASE_PASSWORD`
|
||
- `JWT_AUTH_ENABLE` (`false` для локальной разработки — тогда используется дефолтный пользователь)
|
||
- `OTEL_ENABLE` (`false` локально)
|
||
|
||
Готовые значения-примеры приведены в `.env.example`.
|