iac/apps/document-link/CONFIGURATION.md

96 lines
9.2 KiB
Markdown
Raw Permalink 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.

# Конфигурация проекта document-link (document-link-frontend)
Документ описывает способы конфигурирования и все переменные окружения сервиса публичных ссылок на документы.
## Что это за сервис
`document-link-frontend` — микрофронтенд на **Next.js 13** (App Router, `src/app`), отдающий публичную страницу-карточку документа по ссылке вида `https://document-link.<env>.sarex.io/<uuid>`. По `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 <jwt>`. Берётся из секрета `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.<env>`), `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/<uuid>` (API — `stage-api.sarex.io`).
- Docker: `docker compose up` (порт `8000` → контейнер `3000`).
- В кластере фактически требуется рабочий JWT для сервиса `documentations` (сейчас — `fixedToken`; целевое — секрет `documentations-publiclink-jwt-secret`).