Frontend
Frontend — административный веб-интерфейс DataHUB. Реализует личный кабинет администратора и оператора платформы: управление подключёнными системами, маршрутами, классами сообщений, журналом обмена, пользователями. Технологически — приложение Next.js (App Router, server-side rendering), реализованное на React 19 и TypeScript. Аутентификация — через NextAuth с делегацией к backend.
Эта статья описывает конфигурацию блока frontend. Архитектура самого frontend (структура src/app/, серверные компоненты, маршруты) — в Архитектура / Компоненты системы.
Структура блока
Каталог блока — /etc/datahub/frontend/:
/etc/datahub/frontend/
├── docker-compose.yml # описание контейнера
├── .env.template # шаблон переменных окружения
└── .env # реальные значения (создаётся при установке)
Это самый тонкий блок поставки — у него нет ни данных (./data), ни шаблонов, ни сертификатов, ни логов на хосте. Всё состояние — в JWT-куках браузера пользователя; вся бизнес-логика — на backend.
Файл docker-compose.yml:
services:
frontend:
image: registry.gitlab.com/datahub/v3/services/frontend:dev
container_name: frontend
hostname: frontend
expose:
- "3000"
env_file:
- .env
restart: unless-stopped
networks:
- dh_network
Особенности:
expose: 3000безports— frontend виден только внутриdh_network. Внешние запросы приходят через nginx, который проксирует наhttp://frontend:3000.restart: unless-stopped— в отличие от остальных блоков (restart: always), frontend перезапускается только при сбое, не при ручной остановке. Это нюанс политики Next.js-приложений.- Внутренний
HEALTHCHECK(из Dockerfile) — каждые 30 сек запрашиваетhttp://localhost:3000/healthz. При неготовности контейнер помечаетсяunhealthy.
Образ
Образ собран из исходников Next.js приложения многоступенчатой сборкой:
- Builder —
node:22-slim, выполняетnpm ciиnpm run build(Next.js standalone output). - Runner —
node:22-slim, копирует только.next/standalone,.next/staticиpublic. Запускается под непривилегированным пользователемnextjs.
В runner-образе нет npm, исходников, node_modules — только минимальная среда для запуска. Размер образа порядка 200 МБ.
Конфигурация (.env)
Шаблон .env.template:
AUTH_SECRET={{FRONTEND_AUTH_SECRET}}
HOSTNAME=0.0.0.0
PORT=3000
BACKEND_API_PATH=http://backend:80
API_PROXY_PATH=http://frontend:3000
PASSWORD_MIN_LENGHT=12
PASSWORD_NUMBERS=true
PASSWORD_UPPERCASE_LOWERCASE=true
PASSWORD_SPECIAL_SYMBOLS="@#$%^&+=!"
PASSWORD_HELP="Пароль должен содержать хотя бы одну строчную букву, одну заглавную букву и одну цифру, а так же один из спецсимволов - @#$%^&+=!"
VERIFICATION_TOKEN_LENGTH=6
IS_2FA_ENABLED=true
# NODE_TLS_REJECT_UNAUTHORIZED=0 # отключает проверку TLS сертификатов
| Переменная | Назначение |
|---|---|
AUTH_SECRET |
Секрет NextAuth для подписи session-cookie. Генерируется случайно (см. ниже), не должен совпадать с другими секретами платформы. |
HOSTNAME, PORT |
На каком интерфейсе и порту слушает Next.js. По умолчанию 0.0.0.0:3000. Менять не нужно. |
BACKEND_API_PATH |
URL backend внутри dh_network (для server-side вызовов). По умолчанию http://backend:80. |
API_PROXY_PATH |
URL самого frontend (для случаев, когда frontend через себя проксирует браузерные API-вызовы). По умолчанию http://frontend:3000. |
PASSWORD_MIN_LENGHT |
Минимальная длина пароля при регистрации (учитывается на стороне UI). Должна быть согласована с серверной политикой backend (PASSWORD_COMPLEXITY). |
PASSWORD_NUMBERS, PASSWORD_UPPERCASE_LOWERCASE, PASSWORD_SPECIAL_SYMBOLS |
Требования к составу пароля. Согласовать с backend. |
PASSWORD_HELP |
Текст-подсказка, который отображается пользователю при вводе пароля. |
VERIFICATION_TOKEN_LENGTH |
Длина OTP-кода для подтверждения email/SMS. Согласовать с backend (EMAIL_VERIFICATION_TOKEN_LENGTH, PHONE_VERIFICATION_TOKEN_LENGTH). |
IS_2FA_ENABLED |
Включена ли двухфакторная аутентификация (OTP по email или SMS при входе). |
NODE_TLS_REJECT_UNAUTHORIZED |
Закомментировано. Раскомментировать =0 только для отладки, когда backend использует self-signed сертификат и frontend на server-side не может его проверить. На production-стенде должно быть выключено. |
Генерация AUTH_SECRET
Скопировать результат в AUTH_SECRET без кавычек. Менять AUTH_SECRET на работающей платформе означает разлогинить всех пользователей frontend (их session-cookie перестанут проходить проверку подписи).
Связь с backend
Frontend взаимодействует с backend двумя способами:
- Server-side (Next.js Server Components, API routes) — прямые HTTP-вызовы на
BACKEND_API_PATH=http://backend:80внутриdh_network. Сертификаты не используются (HTTP, не HTTPS — трафик не выходит за пределы сети Docker). - Client-side (браузер пользователя) — браузер обращается к
https://lk.<your-domain>/api/..., эти запросы проходят через nginx → frontend (http://frontend:3000) → backend. То есть frontend выступает proxy для browser → backend через свой server-side endpoint.
Архитектурно это означает: backend никогда не выставлен напрямую в браузер пользователя, frontend знает все его эндпоинты и проксирует только то, что разрешено.
Аутентификация и сессии
Frontend использует NextAuth (v5 beta) в режиме credentials provider — пользователь вводит логин/пароль, NextAuth делегирует проверку backend'у через REST-вызов на ${BACKEND_API_PATH}/api/auth/..., получает JWT-токен, кладёт его в encrypted session-cookie на стороне браузера.
При каждом server-side вызове Next.js достаёт JWT из cookie, расшифровывает, передаёт в backend в заголовке Authorization: Bearer <token>.
Refresh-токен хранится отдельно и используется для тихого обновления access-токена при истечении срока.
Запуск и проверка
После заполнения .env:
Просмотр лога старта:
Ожидаемое сообщение — ▲ Next.js 16.x.x ... Ready in <время>.
Healthcheck:
В колонке STATUS должно быть Up <время> (healthy).
Frontend наружу не выставлен — проверка через nginx:
Должен вернуть OK (это эндпоинт nginx, но при работающем frontend nginx гарантированно его проксирует).
Прямая проверка фронта — в браузере: https://lk.<your-domain>/. Должна открыться страница входа.
Логирование
Frontend пишет логи в stdout/stderr контейнера. Logback-аналога нет — стандартный console.log / console.error Next.js. Доступны через docker logs frontend и попадают в Docker json-file driver (ротация 100 МБ × 10 файлов).
Уровень логирования регулируется самим Next.js — для production-сборки выводятся только ошибки и предупреждения. Дебаг-лог Next.js можно включить переменной NEXT_DEBUG=1, но это шумно и оправдано только при диагностике.
Тонкие особенности
- Standalone mode — образ собран с
output: 'standalone'вnext.config.ts. Это означает, чтоnpmне нужен в runtime — стартуетnode server.js. - Sentry — в
package.jsonесть@sentry/nextjs, но интеграция включается только при наличииSENTRY_DSN(в шаблоне.envне указан). На штатной поставке Sentry не используется. - Telemetry Next.js выключена —
NEXT_TELEMETRY_DISABLED=1(передаётся анонимная статистика разработчикам Next.js; отключено осознанно).
Что дальше
- Reverse Proxy — следующий по порядку запуска блок, обслуживает внешние запросы к frontend.
- Сервер DataHUB — backend, к которому frontend ходит за данными.
- Настройка безопасности — генерация
AUTH_SECRETв общей цепочке секретов платформы. - Архитектура / Компоненты системы — внутреннее устройство frontend.