Qadam Roadmap
проектdocs/operations/environment-matrix.md

Environment matrix и границы доступа

Обновлён 14 апр. 2026 г., 17:16 · 0 комментариев

Environment matrix и границы доступа

Паспорт документа

  • Статус документа: working reference
  • Актуально на: 2 апреля 2026 года
  • Владелец: backend/platform-команда
  • Пересмотр: при изменении env-модели, secret boundaries, сервисов или ownership-модели
  • Область применения: production и local environment-схема для qadam-core, qadam-web и qadam-roadmap
  • Связанные документы:

Цель документа

Этот документ фиксирует, где живут env-переменные, какие сервисы их используют и кто имеет право их менять. Это не список секретных значений. Источником истины здесь являются классы переменных, их владельцы и границы доступа.

1. Источники env по сервисам

СервисRuntimeИсточник envВладелец
qadam-apirollback-only /data/qadam-core/apps/api/dist/main.js/etc/qadam/qadam.envbackend/platform-команда
qadam-api-containerdocker compose runtime для registry image api/etc/qadam/qadam-api-runtime.env + /etc/qadam/qadam.envbackend/platform-команда
qadam-web/data/qadam-web/apps/web/.next/standalone/apps/web/server.js/etc/qadam/qadam.env + systemd PORT=3000, HOSTNAME=127.0.0.1frontend-команда по app logic, backend/platform по production env
qadam-web-runtimedocker compose shadow runtime для registry image product web/etc/qadam/qadam-web-runtime.env + shell/runtime vars QADAM_WEB_*frontend-команда по app logic, backend/platform по runtime contour
qadam-roadmap/data/qadam-web/apps/roadmap/.next/standalone/apps/roadmap/server.js/etc/qadam/qadam-roadmap.envbackend/platform-команда
qadam-core-runner/opt/act_runner/qadam-core/act_runner daemonsystemd unit + /opt/act_runner/qadam-core/.runnerbackend/platform-команда
qadam-monitor/data/qadam-core/scripts/monitor-runtime.mjs/etc/qadam/qadam.env + /etc/qadam/qadam-monitor.envbackend/platform-команда
qadam-backup/data/qadam-core/scripts/backup-runtime.mjs/etc/qadam/qadam.env + /etc/qadam/qadam-backup.envbackend/platform-команда

2. Канонические production env-группы

Backend API (/etc/qadam/qadam.env)

ПеременнаяОбязательностьСекретНазначение
NODE_ENVобязательнанетрежим runtime
PORTобязательнанетлокальный порт API, сейчас 5001
HOSTNAMEобязательнанетbind host, сейчас loopback
DATABASE_URLобязательнадаподключение к production PostgreSQL
REDIS_URLусловно обязательнадаRedis для refresh/session infrastructure
JWT_SECRETобязательнадаподпись access/refresh token
CORS_ORIGINобязательнанетbrowser origin для web
PUBLIC_WEB_BASE_URLопциональнанетcanonical public base URL для backend-generated SEO metadata; если не задан, backend выводит его из NEXT_PUBLIC_API_URL
UPLOADS_DIRусловно обязательнанетлокальный storage для image uploads при OBJECT_STORAGE_DRIVER=local
OBJECT_STORAGE_DRIVERусловно обязательнанетstorage driver для product media: local или s3
S3_ENDPOINTусловно обязательнанетendpoint S3-совместимого storage при OBJECT_STORAGE_DRIVER=s3
S3_REGIONусловно обязательнанетregion/object storage region
S3_BUCKETусловно обязательнанетbucket для product media
S3_ACCESS_KEY_IDусловно обязательнадаaccess key для object storage
S3_SECRET_ACCESS_KEYусловно обязательнадаsecret key для object storage
S3_PUBLIC_BASE_URLопциональнанетCDN/public base URL, если раздача идёт не напрямую через bucket endpoint
S3_FORCE_PATH_STYLEопциональнанетрежим совместимости для MinIO и части S3-compatible провайдеров
S3_OBJECT_ACLопциональнанетcanned ACL для новых объектов; для текущего Spaces-контура нужен public-read
AXIOM_TOKENопциональнадавнешняя отправка логов
AXIOM_DATASETопциональнанетdataset для Axiom
TELEGRAM_BOT_TOKENопциональнадаTelegram integration для operational alerts и мониторинга
TELEGRAM_ALERT_CHAT_IDопциональнанетchat/channel ID для operational alerts и health-уведомлений
SELLER_TELEGRAM_BOT_TOKENопциональнадаотдельный bot token для seller-facing Telegram notifications и onboarding webhook
SELLER_TELEGRAM_BOT_USERNAMEопциональнанетusername seller-facing бота для UX/handoff (@qadam_notify_bot и т.п.)
SELLER_TELEGRAM_WEBHOOK_SECRETопциональнадаsecret token, который Telegram присылает в X-Telegram-Bot-Api-Secret-Token для seller webhook
SMTP_HOSTопциональнанетSMTP host для seller email fallback
SMTP_PORTопциональнанетSMTP port для seller email fallback
SMTP_SECUREопциональнанетвключает SMTPS/TLS режим (true/false)
SMTP_USERопциональнадаSMTP username, если transport требует auth
SMTP_PASSопциональнадаSMTP password, если transport требует auth
SMTP_FROMопциональнанетsender/from для seller email notifications
SMTP_REPLY_TOопциональнанетreply-to адрес для seller email notifications
SELLER_STATUS_CHANGE_NOTIFY_STATUSESопциональнанетCSV-список lead statuses, по которым backend шлёт owner-facing status-change notifications при staff-driven update; по умолчанию CONTACTED,ENROLLED,REJECTED

API container runtime (/etc/qadam/qadam-api-runtime.env)

ПеременнаяОбязательностьСекретНазначение
QADAM_API_IMAGEобязательнанетregistry image tag для production API container runtime
QADAM_API_PORTобязательнанетloopback-порт container runtime, сейчас 5002
QADAM_API_HOSTNAMEобязательнанетbind host для container runtime, сейчас 127.0.0.1
QADAM_API_ENV_FILEобязательнанетenv-файл, который пробрасывается в контейнер, сейчас /etc/qadam/qadam.env
QADAM_API_COMPOSE_PROJECTобязательнанетcompose project name для API runtime

Product web (/etc/qadam/qadam.env)

ПеременнаяОбязательностьСекретНазначение
NEXT_PUBLIC_API_URLобязательнанетbrowser URL API
API_URLобязательнанетserver-side URL API, в текущем production host runtime должен указывать на http://127.0.0.1:5002/api/v1
PORTзадаётся systemdнетлокальный порт web, сейчас 3000
HOSTNAMEзадаётся systemdнетbind host, сейчас loopback

Product web shadow/container runtime (/etc/qadam/qadam-web-runtime.env)

ПеременнаяОбязательностьСекретНазначение
NODE_ENVобязательнанетрежим runtime, сейчас production
API_URLобязательнанетserver-side URL API внутри контейнера; в текущем shadow runtime должен указывать на http://host.docker.internal:5002/api/v1
NEXT_PUBLIC_API_URLобязательнанетbrowser URL API

Дополнительные shell/runtime переменные этого контура задаются через deploy/env/web-runtime.env.example или через одноразовый shell-export:

ПеременнаяОбязательностьСекретНазначение
QADAM_WEB_IMAGEобязательнанетregistry image tag для product web runtime
QADAM_WEB_PORTобязательнанетloopback-порт shadow runtime, сейчас 3002
QADAM_WEB_BIND_HOSTобязательнанетbind host shadow runtime, сейчас 127.0.0.1
QADAM_WEB_ENV_FILEобязательнанетenv-файл, который пробрасывается в контейнер, сейчас /etc/qadam/qadam-web-runtime.env
QADAM_WEB_COMPOSE_PROJECTобязательнанетcompose project name для product web runtime

Roadmap service (/etc/qadam/qadam-roadmap.env)

ПеременнаяОбязательностьСекретНазначение
PORTобязательнанетлокальный порт roadmap, сейчас 3001
HOSTNAMEобязательнанетbind host, сейчас loopback
QADAM_PROJECT_ROOTобязательнанетcheckout канонических docs, сейчас /data/qadam-core
QADAM_ROADMAP_STORAGE_DIRобязательнанетuploads/comments storage roadmap

Gitea Actions runner (/opt/act_runner/qadam-core/.runner)

Переменная / источникОбязательностьСекретНазначение
.runnerобязательнадарегистрационное состояние runner и привязка к eldar/qadam-core
qadam-core-runner.serviceобязательнанетсистемный запуск act_runner daemon

External runtime monitor (/etc/qadam/qadam-monitor.env)

ПеременнаяОбязательностьСекретНазначение
QADAM_MONITOR_PRODUCT_URLобязательнанетпубличный URL product web для uptime-check
QADAM_MONITOR_API_READY_URLобязательнанетreadiness URL API для внешней проверки
QADAM_MONITOR_ROADMAP_URLобязательнанетпубличный URL roadmap-сервиса
QADAM_MONITOR_ROADMAP_BASIC_USERобязательнанетbasic auth login для roadmap uptime-check
QADAM_MONITOR_ROADMAP_BASIC_PASSобязательнадаbasic auth password для roadmap uptime-check
QADAM_MONITOR_TIMEOUT_MSопциональнанетtimeout HTTP-check'ов
QADAM_MONITOR_TLS_WARNING_DAYSопциональнанетпорог warning по сроку жизни TLS-сертификата
QADAM_MONITOR_STATE_FILEобязательнанетstate file для dedupe/recovery логики алертов

Automated backup (/etc/qadam/qadam-backup.env)

ПеременнаяОбязательностьСекретНазначение
QADAM_BACKUP_ROOT_DIRобязательнанетлокальный root для snapshot-каталогов
QADAM_BACKUP_TMP_DIRобязательнанетвременный каталог для сборки off-host archive
QADAM_BACKUP_LOCAL_RETENTION_DAYSобязательнанетсрок хранения локальных snapshot-каталогов
QADAM_BACKUP_OFFSITE_ENABLEDобязательнанетвключает off-host upload в S3-compatible storage
QADAM_BACKUP_OFFSITE_BUCKETопциональнанетbucket для off-host archive; по умолчанию берётся из S3_BUCKET
QADAM_BACKUP_OFFSITE_PREFIXобязательнанетпрефикс object key для backup archive
QADAM_BACKUP_OFFSITE_RETENTION_DAYSобязательнанетсрок хранения off-host archive
QADAM_BACKUP_NOTIFY_ON_SUCCESSопциональнанетразрешает обычные success-уведомления в Telegram; fail и recovery отправляются автоматически по смене состояния
QADAM_BACKUP_STATE_FILEобязательнанетstate file последнего backup-run
QADAM_BACKUP_PG_DUMP_BINобязательнанетпуть до pg_dump
QADAM_BACKUP_PG_RESTORE_BINобязательнанетпуть до pg_restore

3. Что не должно попадать в репозиторий

  • production secrets;
  • содержимое /etc/qadam/*.env;
  • содержимое /opt/act_runner/qadam-core/.runner;
  • пароли БД, JWT secrets, bot tokens, внешние integration keys;
  • S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY и любые другие object storage credentials;
  • ручные .env с боевыми значениями;
  • Dockerfile, image layers, committed compose manifests и build args с боевыми секретами;
  • данные из /var/lib/qadam-core и /var/lib/qadam-roadmap.

4. Границы изменения env

Backend/platform-команда меняет

  • production env-файлы в /etc/qadam;
  • systemd units;
  • nginx конфигурацию;
  • DATABASE_URL, REDIS_URL, JWT_SECRET, UPLOADS_DIR, OBJECT_STORAGE_DRIVER, S3_*, QADAM_PROJECT_ROOT;
  • PUBLIC_WEB_BASE_URL, если backend начинает отдавать canonical/SEO URLs;
  • TLS, домены и bind policy.
  • qadam-monitor.service, qadam-monitor.timer и /etc/qadam/qadam-monitor.env.
  • qadam-backup.service, qadam-backup.timer и /etc/qadam/qadam-backup.env.

Frontend-команда меняет

  • локальные dev .env в qadam-web;
  • frontend-only env для локальной разработки и preview-контуров;
  • не меняет production secrets напрямую.

Совместное согласование требуется

  • при изменении API_URL / NEXT_PUBLIC_API_URL;
  • при изменении PUBLIC_WEB_BASE_URL или любой backend-generated canonical/SEO URL;
  • при изменении auth-контуров или cookie-модели;
  • при появлении нового обязательного env для web-flow;
  • при изменении OpenAPI source/workflow;
  • при смене режима OBJECT_STORAGE_DRIVER, bucket/public URL или политики доступа product media.

5. Принцип для docker и object storage secrets

  • Production credentials не вшиваются в Dockerfile, image layers или в git-managed manifests.
  • Для текущего mixed runtime secrets поставляются через /etc/qadam/*.env.
  • Для действующего docker/image-based runtime API и для будущего image-based runtime остальных сервисов те же secrets должны поставляться через runtime env/secrets механизмы, а не через docker build.
  • Dockerfile может содержать только несекретные build-time параметры.

6. Local development matrix

qadam-core

  • файл: qadam-core/.env
  • владелец локальной конфигурации: backend/platform-команда
  • типовая связка:
    • PORT=5001
    • локальная PostgreSQL
    • локальный Redis
    • CORS_ORIGIN=http://localhost:3000

qadam-web

  • файл: qadam-web/.env
  • владелец локальной конфигурации: frontend-команда
  • типовая связка:
    • NEXT_PUBLIC_API_URL=http://localhost:5001/api/v1
    • API_URL=http://localhost:5001/api/v1
    • OPENAPI_SCHEMA_URL=""
    • QADAM_PROJECT_ROOT="" или checkout qadam-core

7. Изменение env как change package

Любое изменение env-модели считается change package и должно включать:

  1. обновление этого документа;
  2. обновление deployment-runbook.md, если меняется production runtime;
  3. обновление current-state.md, если поменялось фактическое состояние сервера;
  4. обновление project/project-change-log.md;
  5. если изменение затрагивает frontend — обновление frontend-change-log.md.

8. Минимальный контроль доступа

  • Production env правится только с root-доступом на сервере.
  • Репозитории qadam-core и qadam-web не считаются местом хранения production secrets.
  • Любое новое обязательное secret-поле должно сопровождаться обновлением этого документа и runbook.