# Конфигурация проекта document-link (document-link-frontend) Документ описывает способы конфигурирования и все переменные окружения сервиса публичных ссылок на документы. ## Что это за сервис `document-link-frontend` — микрофронтенд на **Next.js 13** (App Router, `src/app`), отдающий публичную страницу-карточку документа по ссылке вида `https://document-link..sarex.io/`. По `uuid` фронтенд запрашивает метаданные документа у сервиса `documentations` и показывает название, автора, версию, размер, срок действия ссылки и кнопку скачивания (см. `ENDPOINTS.md`). Собственного бэкенда у сервиса нет — это чистый фронтенд, поэтому файлы вида `openapi.yaml` для него неприменимы. ## Способы конфигурирования В отличие от бэкенд-сервисов, у фронтенда **нет разбора переменных окружения в коде**. На текущий момент: - Базовый хост API выбирается в рантайме по `window.location.hostname` в `src/app/[uuid]/components/modal.tsx` (жёстко заданный `switch`), а не из переменной окружения; - JWT для авторизации запроса **зашит в коде** (константа `fixedToken` в том же файле) — временное решение; - Обращений к `process.env` / `NEXT_PUBLIC_*` в `src/` нет. При этом конфигурационная поверхность **объявлена в инфраструктуре** (Helm-чарт репозитория и CI) в виде переменных `NEXT_PUBLIC_*` — их предполагается использовать вместо хардкода. Ниже описаны и код, и инфраструктурные объявления. Источники переменных по способам запуска: | Способ запуска | Откуда берутся значения | | --- | --- | | Локально (`npm run dev`) | Значения зашиты в коде; `apiBaseUrl` для `localhost` → `stage-api.sarex.io` | | Локально (Docker / `docker-compose`) | `Dockerfile` (`node:18-alpine`, `next build`, `ENTRYPOINT npm start`, порт `3000`); `docker-compose.yaml` пробрасывает `8000:3000` | | Kubernetes — репозиторный чарт | `.helm/values.yaml`: блок `services.frontend.envs` и `secretEnvs` (см. ниже) | | Kubernetes — infra (этот репозиторий) | `apps/document-link/base` (kustomize) и `apps/document-link/{brusnika-stage,brusnika-prod}` (FluxCD `HelmRelease` поверх `universal-chart`) | | CI/CD (GitLab) | `.gitlab-ci.yml`: `generic/common-ci` (`universal-pipeline`, ref `apps-business`), `SERVICE_NAME=document-link` | ## Переменные приложения Объявлены в `.helm/values.yaml` исходного репозитория. **Важно:** текущий код фронтенда их не читает (см. раздел «Замечания»). | Переменная | Тип | Значение по умолчанию | Назначение | | --- | --- | --- | --- | | `NEXT_PUBLIC_API_BASE_URL` | string | `stage-api.sarex.io` (stage), `api.sarex.io` (production) | Базовый хост API (сервис `documentations`), без схемы | | `NEXT_PUBLIC_API_TOKEN` | string (secret) | — | JWT сервисного аккаунта для `Authorization: Bearer `. Берётся из секрета `documentations-publiclink-jwt-secret` (ключ `jwt`) | ## Базовые хосты API по окружениям Логика `src/app/[uuid]/components/modal.tsx` (`switch` по `window.location.hostname`): | Hostname фронтенда | `apiBaseUrl` | | --- | --- | | `localhost` | `stage-api.sarex.io` | | `document-link.stage.sarex.io` | `stage-api.sarex.io` | | `document-link.sarex.io` | `api.sarex.io` | | прочее | не определён (ошибка в консоль, fallback `stage-api.sarex.io`) | ## Сборка и контейнер | Параметр | Значение | Где задано | | --- | --- | --- | | Базовый образ | `node:18-alpine` | `Dockerfile` | | Команда сборки | `npm i` → `npm run build` (`next build`) | `Dockerfile` | | Entrypoint | `npm start` (`next start`) | `Dockerfile` | | Порт приложения | `3000` | `Dockerfile` (`EXPOSE 3000`), `.helm/values.yaml` (`port._default: 3000`) | | Образ (registry) | `cr.yandex/crp3ccidau046kdj8g9q/document-link-frontend` | `.helm/values.yaml`, infra `HelmRelease` | ## Деплой (infra: `apps/document-link`) | Оверлей | Механизм | Особенности | | --- | --- | --- | | `base` | kustomize (`Deployment` + `Service` + `Namespace`) | namespace `document-link` c `istio-injection: enabled`; `Deployment/frontend` | | `brusnika-stage` | FluxCD `HelmRelease` → `universal-chart` `0.1.7` | `replicaCount`: stage `1`; probes выключены | | `brusnika-prod` | FluxCD `HelmRelease` → `universal-chart` `0.1.7` | `replicaCount`: preprod/production `3`; probes выключены | | `yc-k8s-test` | kustomize (`../base`) | тестовый контур | Порты сервиса: в `universal-chart` — `service.port 8080` → `targetPort 3000` (`portName: http`); в `base/service.yaml` — `port 80` → `targetPort 80`. ## Переменные в CI (`.gitlab-ci.yml`) Пайплайн подключает общие шаблоны `generic/common-ci` (`common-security-scan.yaml`, `universal-pipeline.yaml`, ref `apps-business`). Ключевые переменные: `SERVICE_NAME=document-link`, `DOCKERFILE_PATH=./Dockerfile`, `CI_TRIGGER_SOURCE=app`. Окружение переключается по ветке/тегу: | Условие | STAND | Namespace | Chart | | --- | --- | --- | --- | | `merge_request_event` | — | — | `ENABLE_BUILD_IMAGE=false` (только проверки) | | ветка `stage` | `stage` | `documentations` | `document-link` `0.1.7`, `--build-arg ENV=stage` | | ветка `master` | `preprod` | `document-link-preprod` | `document-link` `0.1.7`, `--build-arg ENV=preprod` | | тег (`CI_COMMIT_TAG`) | `production` | `document-link-prod` | `document-link` `0.1.7`, `--build-arg ENV=prod` | `HELM_SET_ARGS` пробрасывает в `universal-chart` образ (`services.frontend.image.name.`), `global.env`, а также `commitSha`/`gitlabUri`/`gitlabJobUrl`/`owner`. ## Замечания и потенциальные проблемы - **Env-переменные не используются кодом.** `NEXT_PUBLIC_API_BASE_URL` и `NEXT_PUBLIC_API_TOKEN` объявлены в `.helm/values.yaml`, но `src/` их не читает: базовый хост берётся из `switch` по `hostname`, а токен зашит константой `fixedToken`. Для корректной работы на разных стендах логику стоит перевести на `process.env.NEXT_PUBLIC_*` (и тогда `.env.example` станет рабочим шаблоном). - **Зашитый JWT.** Константа `fixedToken` в `modal.tsx` — секрет в исходниках и с ограниченным сроком действия (`exp`). Должен приходить из секрета `documentations-publiclink-jwt-secret` через `NEXT_PUBLIC_API_TOKEN`. - **Неизвестный hostname.** При домене, не входящем в `switch`, `apiBaseUrl` не задаётся явно (используется дефолт `stage-api.sarex.io`) — для новых стендов список нужно расширять. - **Расхождение портов.** Приложение слушает `3000` (Dockerfile/helm `targetPort`), но `apps/document-link/base/deployment.yaml` объявляет `containerPort: 80`, а `base/service.yaml` — `port/targetPort 80`. В `universal-chart` (`HelmRelease`) — корректный `targetPort 3000`. Kustomize-`base` стоит выровнять на `3000`. - **Многоступенчатый Dockerfile закомментирован.** Финальный `runner`-stage отключён — образ запускается из `builder` с полным `node_modules`; для прод-образа стоит включить slim-runner. ## Минимальный набор для запуска - Локально: `npm i && npm run dev`, открыть `http://localhost:3000/` (API — `stage-api.sarex.io`). - Docker: `docker compose up` (порт `8000` → контейнер `3000`). - В кластере фактически требуется рабочий JWT для сервиса `documentations` (сейчас — `fixedToken`; целевое — секрет `documentations-publiclink-jwt-secret`).