iac/apps/contracts/CONFIGURATION.md

136 lines
12 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.

# Конфигурация проекта contracts
Документ описывает все переменные окружения и способы конфигурирования сервиса `contracts` (Go, HTTP API + CLI миграций).
## Способы конфигурирования
Сервис настраивается **только через переменные окружения**. Разбор выполняется библиотекой [`github.com/sethvargo/go-envconfig`](https://github.com/sethvargo/go-envconfig) по структуре `Config` в `internal/app/http/config.go`. Дополнительно `.env`-файл автоматически подгружается через [`github.com/joho/godotenv`](https://github.com/joho/godotenv):
- HTTP-процесс (`cmd/http/main.go`) вызывает `godotenv.Load(".env")` перед разбором конфигурации — если файл `.env` есть в рабочем каталоге, его переменные попадают в окружение;
- CLI-процесс (`cmd/cli/main.go`) загружает файл из `ENV_FILE` (или `.env` по умолчанию), путь можно задать флагом `-env-file`.
Особенности разбора (`go-envconfig`):
- глобального префикса нет — верхнеуровневые поля читаются по своим именам (`LOG_LEVEL`, `ADDRESS`);
- вложенные секции задаются префиксом на уровне структуры: `Database``env:", prefix=DB_"`, `Auth``env:", prefix=AUTH_"`;
- значения по умолчанию заданы в тегах через `default=…`; поля без `default` при отсутствии переменной остаются пустыми (нулевым значением типа), а не приводят к панике на этапе разбора — ошибки всплывают позже (например, невалидный `DB_URL` или пустой `PUBLIC_KEY`).
Отдельного конфиг-файла (yaml/toml) у приложения нет.
Источники переменных по способам запуска:
| Способ запуска | Откуда берутся переменные |
| --- | --- |
| Локально (бинарник) | `.env` в рабочем каталоге (авто-загрузка `godotenv`) + переменные окружения процесса |
| Локально (docker-compose) | `docker-compose.yml`: сервис `contracts` берёт переменные из `env_file: .env`; поднимается вместе с `postgres` |
| Kubernetes (Helm) | `.helm/values-<env>.yaml`: блоки `envs` (обычные значения) и `secrets` (значения из k8s-секретов); шаблон `.helm/templates/deployment.yaml` |
| CI/CD (GitLab) | `.gitlab-ci.yml`: общие шаблоны `generic/common-ci` и переменные `workflow.rules` (namespace, release, chart) |
Способы запуска процессов:
| Команда | Точка входа | Назначение |
| --- | --- | --- |
| `http` | `cmd/http/main.go` | HTTP API (Fiber v3), слушает `ADDRESS` |
| `cli migrate` | `cmd/cli/main.go` | Применение миграций БД (`golang-migrate`), каталог `DB_MIGRATIONS_PATH` |
Порядок запуска в контейнере (`entrypoint.sh`): сначала `./cli migrate`, затем `./http`.
## Переменные приложения
В столбце «Переменная» указано полное имя (с учётом префикса секции). Дефолт `—` означает, что значения по умолчанию нет.
### App
| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `LOG_LEVEL` | string | `debug` | Уровень логирования (zap): `debug`/`info`/`warn`/`error` и т.п. |
| `ADDRESS` | string | `:8080` | Адрес и порт прослушивания HTTP-сервера (Fiber) |
### Database (`DB_*`)
| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `DB_URL` | string | — | DSN подключения к PostgreSQL (`pgxpool.ParseConfig`), напр. `postgres://user:pass@host:5432/db?sslmode=verify-full` |
| `DB_POOL_SIZE` | int32 | `10` | Максимальный размер пула соединений (`pgxpool.Config.MaxConns`) |
### Auth (`AUTH_*`)
| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `AUTH_PUBLIC_KEY` | string | — | Публичный RSA-ключ (PEM) для проверки JWT. См. замечание ниже — фактически используется `PUBLIC_KEY` |
| `PUBLIC_KEY` | string | — | Публичный RSA-ключ (PEM). Читается напрямую в `cmd/http/main.go` через `os.Getenv("PUBLIC_KEY")` и записывается в `config.Auth.PublicKey`, перекрывая `AUTH_PUBLIC_KEY` |
> При старте `AuthProvider` парсит ключ (`pem.Decode` + `x509.ParsePKIXPublicKey`). Если `PUBLIC_KEY` пустой или невалидный — приложение падает с `panic` ещё до старта HTTP-сервера.
## Переменные CLI (миграции)
Читаются в `cmd/cli/main.go` (структура `cliConfig`, префикс `DB_`).
| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `DB_URL` | string | — | DSN подключения к PostgreSQL для применения миграций (обязателен, иначе ошибка `DB_URL is required`) |
| `DB_MIGRATIONS_PATH` | string | `migrations` | Путь к каталогу с SQL-миграциями (`golang-migrate`) |
| `ENV_FILE` | string | `.env` | Путь к `.env`-файлу, из которого CLI загружает переменные (можно задать флагом `-env-file=PATH`) |
## Переменные инфраструктуры и сборки
Не читаются кодом приложения, но участвуют в запуске/сборке/деплое.
| Переменная / параметр | Где используется | Назначение |
| --- | --- | --- |
| `POSTGRES_USER`, `POSTGRES_PASSWORD`, `POSTGRES_DB` | `docker-compose.yml` | Параметры локального контейнера PostgreSQL (`postgres`/`admin`/`postgres`) |
| build-stage `golang:1.24` | `Dockerfile` | Базовый образ для сборки бинарников `http` и `cli` |
| runtime `alpine:latest` | `Dockerfile` | Финальный образ; копируются `http`, `cli`, `migrations/`, `entrypoint.sh`; открыт порт `8080` |
## Переменные из Helm-чарта (`.helm/values-<env>.yaml`)
Обычные значения задаются в блоке `envs` (в текущих values он пуст: `envs: []`). Значения из секретов (блок `secrets`) монтируются как env через `secretKeyRef` в `.helm/templates/deployment.yaml`:
| Переменная | Секрет (`secret_name`) | Ключ (`secret_key`) |
| --- | --- | --- |
| `DB_URL` | `ya-pg-secret` | `db_url` |
| `PUBLIC_KEY` | `public-key` | `key` |
Прочие значения чарта (не переменные приложения): `deployment.*` (имя, образ, порт, реплики, ресурсы, `service_name`/`service_port`), `api.*` (host/prefix/path ingress), `imagePullSecrets`.
Помимо env, чарт монтирует CA-сертификат PostgreSQL из секрета `ya-pg-secret` (ключ `certificate`) как файл `/opt/.postgresql/root.crt` (см. `deployment.yaml`). Секрет `ya-pg-secret` при отсутствии создаётся шаблоном `ya-pg-secret.yaml` со случайными значениями и политикой `helm.sh/resource-policy: keep`.
Параметры окружений (`.helm/values-<env>.yaml`):
| Окружение | `api.host` | `deployment.service_port` |
| --- | --- | --- |
| stage | `stage-api.sarex.io` | `8080` |
| preprod | `api.preprod.sarex.io` | `80` |
| production | `api.sarex.io` | `8080` |
## Переменные в CI (`.gitlab-ci.yml`)
Пайплайн подключает общие шаблоны из `generic/common-ci` (`universal-pipeline-*`, `common-security-scan`, `common-build`) и переключает окружение по ветке/тегу через `workflow.rules`:
| Условие | STAND | Namespace | Chart version |
| --- | --- | --- | --- |
| ветка `master` | `preprod` | `contracts-preprod` | `0.0.1-preprod` |
| ветка `stage` | `stage` | `contracts-stage` | `0.0.1-stage` |
| тег (`CI_COMMIT_TAG`) | `prod` | `contracts-prod` | `0.0.1-prod` |
Общие переменные пайплайна: `RELEASE_NAME=contracts`, `CHART_NAME=contracts`, `IMAGE_PATH=deployment.image`, `HELM_SET_ARGS="--set deployment.image=${IMAGE_NAME}"`, `DOCKERFILE_PATH=Dockerfile`, флаги `ENABLE_BUILD_CHART`/`ENABLE_BUILD_IMAGE`/`ENABLE_STATE_UPDATE`/`ENABLE_DEPLOY` (`true`), `ENABLE_LINTER` (`false`). Для merge request-ов пайплайн запускается без деплоя.
## Замечания и потенциальные проблемы
- **Дублирование ключа авторизации.** В `Config` объявлено поле `Auth.PublicKey` с тегом `AUTH_PUBLIC_KEY`, но `cmd/http/main.go` дополнительно читает `os.Getenv("PUBLIC_KEY")` и перезаписывает им значение. В Helm секрет прокидывается как `PUBLIC_KEY`. Практически используется именно `PUBLIC_KEY`; `AUTH_PUBLIC_KEY` в текущем деплое не задаётся.
- **`.env` загружается автоматически** (в отличие от Python-сервисов): `godotenv.Load(".env")` в HTTP-процессе и `godotenv.Load(ENV_FILE|.env)` в CLI. Файл `.env` при этом попадает под `.gitignore` (`*.env`) и в репозиторий не коммитится.
- **Пустой `PUBLIC_KEY` — фатально.** `auth.New` делает `panic`, если ключ не удаётся распарсить как PEM/PKIX. Для локального запуска нужен валидный публичный ключ.
- **`DB_URL` обязателен и для http, и для cli.** Невалидный DSN приводит к ошибке `pgxpool.ParseConfig`/подключения; в CLI пустой `DB_URL` даёт явную ошибку `DB_URL is required`.
- **`envs: []` в values.** Все прикладные переменные в k8s сейчас приходят только из секретов (`DB_URL`, `PUBLIC_KEY`); `LOG_LEVEL`/`ADDRESS` используют дефолты (`debug`, `:8080`).
## Минимальный набор для локального запуска
PostgreSQL поднимается через `docker-compose up postgres`, приложение — сборкой `cmd/http` (или целиком через docker-compose). Минимально необходимо задать:
- `DB_URL` — DSN до PostgreSQL (для локали обычно `?sslmode=disable`)
- `PUBLIC_KEY` — валидный публичный RSA-ключ (PEM) для проверки JWT
- при необходимости: `LOG_LEVEL`, `ADDRESS`, `DB_POOL_SIZE` (иначе применяются дефолты)
- для миграций (`cli migrate`): `DB_URL` и, при нестандартном расположении, `DB_MIGRATIONS_PATH`
Готовые значения-примеры приведены в `.env.example`.