Перейти к основному содержимому

Переменные окружения

Справочник переменных окружения всех частей монорепозитория «Оптимы». Значения секретов здесь не приводятся: в production они задаются per-окружение в Coolify, в репозитории лежат только заглушки для локальной разработки и CI.

Бэкенд (backend/)​

Источник истины — zod-схема backend/src/core/config/env.schema.ts. Пример — backend/.env.example (локально скопируйте его в backend/.env). Приложение валидирует env при старте: если обязательная переменная отсутствует или некорректна, процесс падает до приёма трафика со списком нарушений.

В production дополнительно действует проверка «боевой пригодности» секретов (backend/src/core/crypto/secret-strength.ts, ADR-0044): активный ключ шифрования, JWT_ACCESS_SECRET и JWT_REFRESH_SECRET не должны совпадать с заглушками из репозитория, содержать маркеры вроде change-me или иметь низкую энтропию, а JWT-секреты не должны совпадать между собой. Иначе контейнер не стартует.

Приложение и инфраструктура​

ПеременнаяОбязательнаПо умолчаниюНазначение
NODE_ENVнетdevelopmentdevelopment / test / production. Влияет на Swagger, Bull Board, /metrics, CORS, проверку секретов. В Docker-образе задан production
PORTнет3000порт HTTP-сервера
LOG_LEVELнетпо NODE_ENV: production — log, test — warn, иначе debugминимальный уровень структурных JSON-логов: error / warn / log / debug / verbose
DATABASE_URLда—строка подключения PostgreSQL postgres://user:pass@host:port/db. Нужен PostgreSQL с расширением pgvector
REDIS_URLда—строка подключения Redis redis://[user:pass@]host:port[/db]
QUEUE_PREFIXнетoptimaпрефикс ключей BullMQ; изолирует окружения, если они делят один Redis
GIT_SHAнет—SHA коммита для ответа GET /version. Сейчас ни Dockerfile, ни CI его не передают
TRUST_PROXY_HOPSнет1число доверенных прокси для X-Forwarded-For (Coolify/Traefik). 0 — прямое подключение
CORS_ORIGINSнет—production: разрешённые origin'ы через запятую. Без переменной CORS-заголовки не выдаются. В dev/test CORS открыт

Аутентификация и шифрование​

ПеременнаяОбязательнаПо умолчаниюНазначение
JWT_ACCESS_SECRETда—секрет подписи access-токенов, не короче 16 символов
JWT_REFRESH_SECRETда—не короче 16 символов. Устарела: refresh-токены opaque и этим секретом не подписываются, переменная оставлена для совместимости. Её ротация не завершает сессии
JWT_ACCESS_TTLнет15mсрок жизни access-токена (формат ms: 15m, 1h)
JWT_REFRESH_TTLнет30dсрок жизни refresh-токена
ENCRYPTION_KEYSда—key-ring AES-256-GCM для секретов at-rest (API-ключи кабинетов WB): kid:hex64[,kid:hex64…], ключ — openssl rand -hex 32 (ADR-0005)
ENCRYPTION_ACTIVE_KIDда—kid из ENCRYPTION_KEYS, которым шифруются новые записи
AUTH_MAX_FAILED_ATTEMPTSнет10неудачных входов до временной блокировки учётной записи
AUTH_LOCKOUT_MSнет900000 (15 мин)длительность блокировки

Порядок ротации ключа шифрования описан в backend/README.md (раздел «Ротация ключа шифрования»).

Служебные интерфейсы (production)​

В dev/test эти интерфейсы открыты. В production каждый подключается только при наличии обеих переменных пары и закрывается HTTP Basic; без них интерфейс отключён.

ПеременныеЧто защищают
SWAGGER_USER, SWAGGER_PASSWORDSwagger UI /api/docs
QUEUE_BOARD_USER, QUEUE_BOARD_PASSWORDBull Board /admin/queues
METRICS_USER, METRICS_PASSWORDPrometheus /metrics

Входящий rate limiting​

Подробнее — Обзор API, раздел «Входящий rate limiting».

ПеременнаяПо умолчаниюНазначение
THROTTLE_DEFAULT_LIMIT300общий лимит запросов с IP за окно
THROTTLE_DEFAULT_TTL_MS60000окно общего лимита
THROTTLE_AUTH_LIMIT5попыток register/login с IP за окно
THROTTLE_AUTH_TTL_MS900000окно auth-лимита (15 мин)
THROTTLE_REFRESH_LIMIT60запросов POST /auth/refresh с IP за окно
THROTTLE_REFRESH_TTL_MS60000окно refresh-лимита
THROTTLE_LLM_LIMIT30вызовов эндпоинтов с LLM с IP за окно
THROTTLE_LLM_TTL_MS3600000окно LLM-лимита (1 ч)

THROTTLE_REFRESH_* читаются напрямую из process.env декоратором (backend/src/core/security/throttle.decorators.ts) и в zod-схему не входят: некорректное значение не уронит старт, а молча заменится значением по умолчанию.

Интеграция с Wildberries​

Подробнее — Интеграция с WB API.

ПеременнаяПо умолчаниюНазначение
WB_API_USE_SANDBOXfalseиспользовать sandbox-домены WB (только с токеном «Тестовый контур»). Для категорий без sandbox — явная ошибка
WB_API_TIMEOUT_MS10000таймаут одного запроса к WB
WB_API_RETRY_ATTEMPTS3максимум попыток HTTP-запроса, включая первую (1–10)
WB_API_RETRY_BASE_MS500база экспоненциального backoff для 5xx и сетевых сбоев
WB_API_RATE_LIMIT_MAX_WAIT_MS30000нижняя граница потолка ожидания лимита; эффективный потолок — max(значение, N × окно эндпоинта + 5 с)
DIGITIZATION_INCREMENT_INTERVAL_MS30 мин (константа модуля)интервал яруса «инкремент» синхронизации фидов оцифровки
RNP_SYNC_INTERVAL_MS—устаревший синоним предыдущей переменной; читается, если новая не задана
SYNC_QUEUE_CONCURRENCY5 (константа)сколько кабинетов один процесс синхронизирует параллельно в каждой sync-очереди (ADR-0040)

ИИ-провайдер (LLM)​

Все переменные необязательны: без них приложение стартует, а вызов ИИ вернёт LLM_UNAVAILABLE (ADR-0014).

ПеременнаяПо умолчаниюНазначение
LLM_PROVIDERopenai-compatibleтип адаптера; других значений пока нет
LLM_BASE_URL—базовый URL OpenAI-совместимого API
LLM_API_KEY—ключ провайдера (секрет; для локальных эндпоинтов может быть пустым)
LLM_MODEL—модель чата
LLM_EMBEDDINGS_MODEL—модель эмбеддингов (нужна RAG)
LLM_TIMEOUT_MS30000таймаут одного вызова
LLM_RETRY_ATTEMPTS3максимум попыток (повтор на 429/5xx/сети)
LLM_RETRY_BASE_MS500база backoff
LLM_MAX_RETRY_AFTER_MS30000верхний предел ожидания по Retry-After
LLM_MAX_TOKENS1024потолок max_tokens на вызов, если сервис не задал свой

Ресурсные предохранители​

ПеременнаяПо умолчаниюНазначение
REPORT_MAX_PERIOD_DAYS366максимальная длина периода в отчётах; длиннее — 400
DB_STATEMENT_TIMEOUT_MS30000statement_timeout PostgreSQL; 0 — без лимита. Срабатывание — 503 с Retry-After
DB_MAX_PARALLEL_WORKERS_PER_GATHER0max_parallel_workers_per_gather для соединений приложения; -1 — не задавать. В .env.example отсутствует

Веб-приложение (frontend/)​

Next.js; переменные NEXT_PUBLIC_* встраиваются в сборку, поэтому для образа задаются build-аргументом. Пример — frontend/.env.example, код — frontend/src/env.ts.

ПеременнаяПо умолчанию в кодеПример для локалкиНазначение
NEXT_PUBLIC_API_URLhttp://localhost:3000http://localhost:3000базовый URL API. В Docker-образе по умолчанию https://api.optimawb.ru
NEXT_PUBLIC_LANDING_URLhttps://optimawb.ruhttp://localhost:3002адрес лендинга для ссылок из приложения

Лендинг (landing/)​

Vite; переменные встраиваются в сборку (build-аргументы образа). Пример — landing/.env.example.

ПеременнаяПо умолчанию в кодеВ образеНазначение
VITE_APP_ORIGINhttp://localhost:3001https://app.optimawb.ruадрес веб-приложения (кнопки входа и регистрации)
VITE_DOCS_URLhttps://docs.optimawb.ruhttps://docs.optimawb.ruадрес портала документации

Портал документации (docs-site/)​

ПеременнаяПо умолчаниюНазначение
OPTIMA_SWAGGER_URLhttps://api.optimawb.ru/api/docsссылка на Swagger UI в верхней навигации. В Coolify задаётся per-окружение с отметкой Build Variable и пробрасывается в сборку через ARG в docs-site/Dockerfile

Локальный docker-compose.yml​

ПеременнаяПо умолчаниюНазначение
REDIS_PASSWORDoptima-localпароль Redis (--requirepass); подставляется и в REDIS_URL контейнера backend
NODE_ENVdevelopmentрежим контейнера backend (образ собран с production, compose его переопределяет)
JWT_ACCESS_SECRET, JWT_REFRESH_SECRET, ENCRYPTION_KEYS, ENCRYPTION_ACTIVE_KIDлокальные заглушкиможно переопределить из окружения хоста

DATABASE_URL и REDIS_URL контейнера backend заданы в compose жёстко и указывают на сервисы postgres и redis внутри compose-сети.

Переменные CI​

Workflow backend-ci задаёт для проверок собственные значения (DATABASE_URL, REDIS_URL без пароля, NODE_ENV=test, CI-заглушки JWT и ключа шифрования). Они имеют приоритет над .env.example, который подгружают e2e-тесты. Секреты GitHub для деплоя перечислены на странице CI/CD и деплой.

Связанные страницы​