17 KiB
Конфигурация проекта bim-backend-v2
Документ описывает все переменные окружения и способы конфигурирования сервиса.
Способы конфигурирования
Сервис настраивается только через переменные окружения. Разбор выполняется в config/config.go (функция NewConfig) через библиотеку kelseyhightower/envconfig (структура Config).
Особенности разбора:
- Префикса нет —
envconfig.Process("", &cfg)вызывается с пустым префиксом, поэтому имена переменных задаются как есть (напр.POSTGRES_ADDRESS,API_ADDRESS). Имя переменной определяется тегомenvconfig:"..."у каждого поля. - Типы приводятся автоматически по типу поля Go (
string,int,bool,uint64). Дляboolподходят1/0/true/false. - Ошибка разбора приводит к
panicпри старте (вNewConfigenvconfig.Processзавёрнут вsync.Once, ошибка не возвращается, а паникует). - Отсутствующая переменная не является ошибкой — поле получает нулевое значение соответствующего типа (пустая строка,
0,false). Обязательность полей не проверяется.
В отличие от python-сервисов, приложение загружает .env автоматически: в cmd/httpserver/main.go вызывается godotenv.Load(".env") (если файла нет — печатается предупреждение и используются переменные окружения процесса).
Отдельного конфиг-файла (yaml/toml) у приложения нет.
Источники переменных по способам запуска:
| Способ запуска | Откуда берутся переменные |
|---|---|
| Локально (бинарник) | Файл .env в рабочем каталоге (godotenv.Load) либо переменные окружения процесса |
| Локально (контейнеры) | .docker/docker-compose.yml: env_file → .docker/.env + .docker/.docker.env |
| Kubernetes (Helm, репозиторий приложения) | .helm/values-<env>.yaml: блоки envs (обычные значения) и secrets (из k8s-секретов); шаблон .helm/templates/api.yaml |
| Kubernetes (IaC, этот репозиторий) | iac/apps/bim/base/backend-deployment.yaml: блок env и секреты из Vault (аннотации vault.hashicorp.com/*, шаблон bim-postgresql) |
| CI/CD (GitLab) | .gitlab-ci.yml: подключение общих пайплайнов generic/common-ci и переменные workflow.rules по ветке/тегу |
Способы запуска процессов:
| Команда | Точка входа | Назначение |
|---|---|---|
httpserver (make api → go install ./cmd/httpserver) |
cmd/httpserver/main.go |
HTTP API. При старте применяет миграции (appmigrations.RunOnStartup), поднимает net/http/pprof на :8081, затем запускает API на API_ADDRESS |
migrations (go install ./cmd/migrations) |
cmd/migrations/main.go |
Отдельный запуск миграций БД |
Порядок запуска в контейнере (.docker/entrypoint.sh): запускается /go/bin/httpserver (строка запуска миграций закомментирована — миграции выполняются самим приложением на старте). Финальный образ (.docker/api.dockerfile) — scratch со статически слинкованным бинарником httpserver и вшитым CA-сертификатом Postgres (/root/yandex_pg.pem).
Переменные приложения
Ниже перечислены все переменные, читаемые кодом (config/config.go). Префикса нет. Дефолт — это нулевое значение типа Go, если переменная не задана.
App
| Переменная | Тип | Значение по умолчанию | Назначение |
|---|---|---|---|
APP_NAME |
string | "" |
Имя приложения (в коде помечено TODO — в deploy-envs не задаётся) |
APP_VERSION |
string | "" |
Версия приложения (TODO — в deploy-envs не задаётся) |
LOG_LEVEL |
string | "" |
Уровень логирования, передаётся в logging.NewLogger (TODO — в deploy-envs не задаётся) |
API_ADDRESS |
string | "" |
Адрес прослушивания HTTP API в формате host:port (напр. 0.0.0.0:8080) |
TEST_ENV |
string | "" |
Служебное поле для тестов |
PostgreSQL
Сервис работает с тремя кластерами PostgreSQL (master, slave-1, slave-2). Выбор кластера для конкретного BIM выполняется по его id в internal/app/http/httpserver.go (сравнение с LAST_MASTER_BIM*/LAST_SLAVE_1_BIM*). Строка подключения собирается в Config.GetPostgresConnectionURL (postgres://user:password@addr:port/db, при ENABLE_SSL=false добавляется ?sslmode=disable).
Master-кластер:
| Переменная | Тип | Назначение |
|---|---|---|
POSTGRES_ADDRESS |
string | Хост PostgreSQL (master) |
POSTGRES_PORT |
string | Порт PostgreSQL (master) |
POSTGRES_USER |
string | Пользователь БД |
POSTGRES_PASSWORD |
string | Пароль пользователя БД |
POSTGRES_DB |
string | Имя базы данных |
POSTGRES_POOL_SIZE |
int | Размер пула соединений |
DB_CERT_PATH |
string | Путь к CA-сертификату PostgreSQL (используется при ENABLE_SSL=1) |
Slave-1 кластер — те же поля с суффиксом _2:
| Переменная | Тип | Назначение |
|---|---|---|
POSTGRES_ADDRESS_2 |
string | Хост PostgreSQL (slave-1) |
POSTGRES_PORT_2 |
string | Порт |
POSTGRES_USER_2 |
string | Пользователь |
POSTGRES_PASSWORD_2 |
string | Пароль |
POSTGRES_DB_2 |
string | База данных |
POSTGRES_POOL_SIZE_2 |
int | Размер пула |
DB_CERT_PATH_2 |
string | Путь к CA-сертификату |
Slave-2 кластер — те же поля с суффиксом _3:
| Переменная | Тип | Назначение |
|---|---|---|
POSTGRES_ADDRESS_3 |
string | Хост PostgreSQL (slave-2) |
POSTGRES_PORT_3 |
string | Порт |
POSTGRES_USER_3 |
string | Пользователь |
POSTGRES_PASSWORD_3 |
string | Пароль |
POSTGRES_DB_3 |
string | База данных |
POSTGRES_POOL_SIZE_3 |
int | Размер пула |
DB_CERT_PATH_3 |
string | Путь к CA-сертификату |
Шардирование BIM по кластерам
| Переменная | Тип | Назначение |
|---|---|---|
LAST_MASTER_BIM |
uint64 | Верхняя граница id BIM для master-кластера (API v1) |
LAST_MASTER_BIM_V3 |
uint64 | Верхняя граница id BIM для master-кластера (API v2 / BIM v3) |
LAST_SLAVE_1_BIM |
uint64 | Верхняя граница id BIM для slave-1 (API v1) |
LAST_SLAVE_1_BIM_V3 |
uint64 | Верхняя граница id BIM для slave-1 (API v2 / BIM v3) |
Прочее
| Переменная | Тип | Значение по умолчанию | Назначение |
|---|---|---|---|
ENABLE_SSL |
bool | false |
Подключение к PostgreSQL по TLS. При false в DSN добавляется sslmode=disable |
ENABLE_SQL_QUERY |
bool | false |
Логировать SQL-запросы |
DJANGO_HOST |
string | "" |
Базовый URL Django-бэкенда для проверки прав администратора (см. ENDPOINTS.md) |
INTEGRATION_TESTS |
bool | false |
Режим интеграционных тестов. При true CheckUserIsAdmin всегда возвращает true |
Переменные, не читаемые приложением (инфраструктура/сборка/тесты)
Присутствуют в .docker/.env, .docker/.docker.env, docker-compose.yml или Helm, но config/config.go их не разбирает.
| Переменная | Где используется | Назначение |
|---|---|---|
API_PORT |
.docker/.env |
Порт API для локального compose |
POSTGRES_EXTERNAL_PORT, POSTGRES_EXTERNAL_PORT_2 |
docker-compose.yml |
Проброс портов контейнеров Postgres |
POSTGRES_ADDRESS2 |
.docker/.docker.env |
Опечатка/легаси (нет суффикса _), кодом не читается |
GRPC_ADDRESS, GRPC_PORT |
.docker/.env |
Объявлены, но кодом не используются |
TEST_BIM, JWT_TEST |
.docker/.env, .docker/.docker.env |
Данные для интеграционных тестов |
POSTGRES_*_4, DB_CERT_PATH_4 |
.helm/values-*.yaml, IaC backend-deployment.yaml |
Четвёртый кластер задаётся в деплое, но config.go доходит только до суффикса _3 |
LAST_SLAVE_2_BIM(_V3), LAST_SLAVE_3_BIM(_V3), LAST_SLAVE_4_BIM(_V3) |
.helm/values-*.yaml |
Заданы в values, но кодом не читаются (актуальны только LAST_MASTER_* и LAST_SLAVE_1_*) |
CI_COMMIT_SHORT_SHA |
.gitlab-ci.yml (build-arg) |
Тег/версия сборки образа |
Переменные из Helm-чарта приложения (.helm/values-<env>.yaml)
Обычные значения задаются в блоке envs для каждого окружения (stage/preprod/production) и содержат те же переменные POSTGRES_*, API_ADDRESS, DJANGO_HOST, ENABLE_SSL, ENABLE_SQL_QUERY, LAST_*, что описаны выше (различаются адресами БД, размерами пула, границами шардирования и доменом Django).
Значения из секретов (блок secrets, монтируются как env через secretKeyRef):
| Переменная | Секрет (secret_name) |
Ключ (secret_key) |
|---|---|---|
POSTGRES_USER |
bim-v2-database-secret |
username |
POSTGRES_PASSWORD |
bim-v2-database-secret |
password |
POSTGRES_USER_2 |
bim-v2-database-secret-2 |
username |
POSTGRES_PASSWORD_2 |
bim-v2-database-secret-2 |
password |
POSTGRES_USER_3 |
bim-v2-database-secret-3 |
username |
POSTGRES_PASSWORD_3 |
bim-v2-database-secret-3 |
password |
POSTGRES_USER_4 |
bim-v2-database-secret-3 |
username |
POSTGRES_PASSWORD_4 |
bim-v2-database-secret-3 |
password |
Ключевые не-env значения чарта: api.name, api.image, api.version, api.port (8080), api.replicas, api.service_name/api.service_port (80), api.service_account, api.requests.memory/cpu, api.api_host, api.api_host_prefix (/bimv2/api/), api.api_path (/api/), api.internal_path (/internal/), api.permitted_ns (namespace'ы, которым разрешён доступ к /internal/*), imagePullSecrets.
Сетевой слой (.helm/templates/mesh-config.yaml, Istio):
VirtualService(приapi.virtual_service.enabled) маршрутизируетapi_host_prefix→api_path, задаёт CORS (allowOrigins—*.sarex.ioиlocalhost,allowHeadersвключаютAuthorization,Content-Type,Identity).AuthorizationPolicyroutes-v2: доступ к/api/*разрешён только от istio-ingressgateway при наличии claimtoken_type=access; доступ к/internal/*— только из namespace'овapi.permitted_ns.
Переменные из IaC-репозитория (iac/apps/bim/)
Деплой в этом репозитории (kustomize) устроен иначе, чем чарт приложения:
base/backend-deployment.yaml— Deploymentbackendв namespacebim, образbim-api,containerPort: 8000,API_ADDRESS=0.0.0.0:8000, health-пробаGET /ping.- Секреты PostgreSQL инъектируются из Vault (аннотации
vault.hashicorp.com/*, рольbim, путьsecrets/data/postgresql/apps/bim) в файл/vault/secrets/bim-postgresql, который экспортируется в окружение перед запуском (set -a; . /vault/secrets/bim-postgresql; set +a; exec ./httpserver). Шаблон Vault задаётPOSTGRES_ADDRESS[_2../_4],POSTGRES_PORT*,POSTGRES_DB*(все указывают наpostgresql.bim.svc.cluster.local:5432, БДbim_db) иPOSTGRES_USER*/POSTGRES_PASSWORD*из Vault. - Прочие env заданы прямо в манифесте:
LAST_MASTER_BIM,LAST_MASTER_BIM_V3,LAST_SLAVE_1_BIM,POSTGRES_POOL_SIZE,DB_CERT_PATH_2/3/4,DJANGO_HOST(http://backend.django.svc.cluster.local:8000),ENABLE_SQL_QUERY=0,ENABLE_SSL=0. - Оверлеи
brusnika-prod,brusnika-stage,yc-k8s-testпатчат base (реплики, образ, postgresql).
Переменные в CI (.gitlab-ci.yml)
Пайплайн подключает общие шаблоны generic/common-ci (universal-pipeline-<env>.yaml, common-security-scan.yaml, common-build.yaml) и переключает окружение по ветке/тегу через workflow.rules:
| Условие | STAND | Namespace |
|---|---|---|
ветка master |
preprod |
bim-api-preprod |
ветка stage |
stage |
bim-api-stage |
тег (CI_COMMIT_TAG) |
prod |
bim-api-prod |
Общие переменные job'ов: RELEASE_NAME=bim-backend-v2, CHART_NAME=bim-backend-v2, CHART_VERSION=0.0.1-<stand>, IMAGE_PATH=api.image, DOCKERFILE_PATH=.docker/api.dockerfile, HELM_SET_ARGS=--set api.image=${IMAGE_NAME}, BUILD_ARGS=--build-arg CI_COMMIT_SHORT_SHA=..., флаги ENABLE_BUILD_CHART/ENABLE_BUILD_IMAGE/ENABLE_STATE_UPDATE/ENABLE_DEPLOY=true, ENABLE_LINTER=false. Стадии: linter → test → unittest → prebuild-secscan → build → state-update → deploy.
Замечания и потенциальные проблемы
- Переменные разбираются без префикса (
envconfig.Process("", ...)) — имена совпадают с тегамиenvconfigполей структурыConfig. - Обязательность полей не валидируется: отсутствующая переменная молча получает нулевое значение. Например пустой
API_ADDRESSприведёт к попытке слушать на":0". - В коде объявлены только три кластера (
POSTGRES_*,_2,_3), тогда как в деплое присутствует и четвёртый (_4). Переменные_4и дополнительныеLAST_SLAVE_2/3/4_*в окружении задаются, но приложением не используются. - Приложение загружает
.envавтоматически (godotenv.Load(".env")); при отсутствии файла ошибки нет — берутся переменные процесса. - В
NewConfigошибкаenvconfig.Processне возвращается, а вызываетpanic(обёрнута вsync.Once).
Минимальный набор для локального запуска
Postgres поднимается через docker-compose (.docker/docker-compose.yml), приложение — через make api и запуск httpserver. Минимально необходимо задать (готовые примеры — в .env.example):
API_ADDRESS- Master-кластер:
POSTGRES_ADDRESS,POSTGRES_PORT,POSTGRES_USER,POSTGRES_PASSWORD,POSTGRES_DB,POSTGRES_POOL_SIZE - Slave-кластеры
_2и_3(те же поля) — сервис создаёт соединения ко всем трём при старте ENABLE_SSL=0,DB_CERT_PATH*(приENABLE_SSL=1)DJANGO_HOSTLAST_MASTER_BIM,LAST_MASTER_BIM_V3,LAST_SLAVE_1_BIM,LAST_SLAVE_1_BIM_V3INTEGRATION_TESTS=0,ENABLE_SQL_QUERYпо необходимости