Reverse Proxy
Nginx — единая точка входа в платформу. Принимает весь внешний трафик, выполняет TLS-терминирование, проксирует запросы на backend и frontend, ограничивает скорость запросов, публикует административные интерфейсы pgAdmin и RabbitMQ Management. Поставляется как отдельный блок Docker Compose.
Эта статья описывает структуру блока nginx и конфигурацию виртуальных серверов. Установка по шагам — в Быстром старте / п. 4.8 «Nginx». Выпуск сертификатов — в Настройке безопасности.
Структура блока
Каталог блока — /etc/datahub/nginx/:
/etc/datahub/nginx/
├── docker-compose.yml # описание контейнера
├── certs/ # TLS-сертификаты и скрипты их выпуска
│ ├── ca.crt, ca.key
│ ├── server.crt, server.key
│ ├── <your-domain>.crt, <your-domain>.key
│ ├── generate-root-CA.sh
│ ├── generate-server-cert.sh
│ └── generate-client-cert.sh
├── config/
│ ├── nginx.conf # глобальная конфигурация
│ └── conf.d/ # серверы для конкретных доменов и портов
│ ├── http.conf # HTTP→HTTPS-редирект
│ ├── lk.<domain>.conf # личный кабинет
│ ├── exchange.<domain>.conf # exchange API
│ ├── pg-admin.conf # reverse-proxy на pgAdmin (порт 15432)
│ └── rmq-admin.conf # reverse-proxy на RabbitMQ Management (порт 15672)
├── html/ # статика (заглушки на корень domain)
├── log/ # access/error логи (bind-mount)
└── scripts/
├── selfsigned/ # генерация self-signed сертификатов
└── letsencrypt/ # автоматизация Let's Encrypt
Файл docker-compose.yml:
services:
nginx:
image: registry.gitlab.com/datahub/v3/services/nginx:main
container_name: nginx
hostname: nginx
environment:
- TZ=Europe/Moscow
volumes:
- ./certs:/etc/nginx/certs:ro
- ./config/nginx.conf:/etc/nginx/nginx.conf:ro
- ./config/conf.d:/etc/nginx/conf.d:ro
- ./html:/usr/share/nginx/html:ro
- ./log/:/var/log/nginx/:rw
- /var/www/letsencrypt:/var/www/letsencrypt:ro
ports:
- "80:80" # redirect to https
- "443:443" # https
# - "18443:18443" # uncomment for single-domain-two-ports
- "15432:15432" # pg-admin reverse proxy
- "15672:15672" # rmq-admin reverse proxy
restart: always
networks:
- dh_network
Это единственный блок поставки с пробросом портов (ports:) — весь остальной трафик платформы изолирован в dh_network.
Глобальная конфигурация (nginx.conf)
config/nginx.conf задаёт глобальные настройки HTTP-уровня и подключает все серверы из conf.d/. Полный файл лежит в шаблоне поставки (devops/deployment-templates/nginx/config/nginx.conf). Ключевые параметры платформы:
| Директива | Значение | Назначение |
|---|---|---|
worker_connections |
1024 |
Максимум одновременных соединений на воркер. |
client_max_body_size |
128m |
Максимальный размер тела запроса. Лимит обусловлен моделью передачи бинарных вложений внутри сообщения (до выпуска S3). |
proxy_buffering |
off |
Стриминговое проксирование без буферизации — важно для long-polling exchange API. |
proxy_read_timeout |
120s |
Согласовано с polling-timeout: 90000 и request-timeout: 120000 в backend. |
keepalive_timeout |
65 |
Сохранение HTTP-keepalive для эффективного proxy на frontend. |
gzip on |
gzip | Сжатие текстовых ответов (text, JSON, JavaScript, CSS). |
limit_req_zone req_per_ip |
rate=10r/s |
Базовый лимит на любой API-эндпоинт с одного IP. |
limit_req_zone auth_per_ip |
rate=5r/m |
Жёсткий лимит на эндпоинты авторизации. |
Логи всех виртуальных серверов пишутся в едином формате datahub_format (ISO-время, статус, request, IP, User-Agent, X-Forwarded-For) — это упрощает анализ через Диагностика / Анализ логов.
Схемы публикации
Платформа поддерживает две схемы публикации внешних сервисов.
Схема по умолчанию: два домена
| Сервис | Адрес | Порт |
|---|---|---|
| Личный кабинет (frontend + backend API) | lk.<your-domain> |
443 |
| Exchange API (только эндпоинты обмена) | exchange.<your-domain> |
443 |
| pgAdmin (опционально) | lk.<your-domain>:15432 |
15432 |
| RabbitMQ Management | lk.<your-domain>:15672 |
15672 |
Конфиги:
conf.d/http.conf— два HTTP-сервера дляlk.<domain>иexchange.<domain>, оба редиректят на HTTPS, обслуживают/.well-known/acme-challenge/для Let's Encrypt.conf.d/lk.<domain>.conf— полный фронт + API, проксирует наfrontend:3000(frontend сам ходит в backend).conf.d/exchange.<domain>.conf— только эндпоинты/api/exchange/и/api/auth/, проксирует напрямую наbackend:80. Корневой запрос отдаёт404.conf.d/pg-admin.conf— слушает порт15432, проксирует наpg-admin:80с поддержкой WebSocket.conf.d/rmq-admin.conf— слушает порт15672, проксирует наrabbitmq:15672.
Альтернативная схема: один домен, два порта
Используется, если заказчик не может или не хочет выпускать второе доменное имя. Личный кабинет переезжает на нестандартный порт (например, 18443), exchange остаётся на 443.
Пример конфигурации лежит в /etc/datahub/nginx/config/conf.d/examples/single-domain-two-ports/ с README. Краткая инструкция применения — в Быстром старте / п. 4.8 «Nginx». После замены конфигов не забыть пробросить порт 18443 в docker-compose.yml блока nginx и открыть его на сетевом firewall.
Виртуальный сервер личного кабинета (lk)
Файл conf.d/lk.<your-domain>.conf обслуживает домен личного кабинета и проксирует на frontend (frontend сам обращается к backend для API-вызовов). Ключевые блоки:
listen 443 ssl;+ сертификат — терминирование HTTPS.- Стандартные proxy-заголовки:
Host,X-Real-IP,X-Forwarded-For,X-Forwarded-Proto. location ^~ /api/auth/— жёсткий лимитauth_per_ip burst=5 nodelay, проксирование наhttp://frontend:3000, отдельный логaccess_auth.log.location ^~ /api/— базовый лимитreq_per_ip burst=20 nodelay, проксирование наhttp://frontend:3000, логaccess_api.log.location ^~ /docs/— документация backend (Swagger UI), проксирование наhttp://backend:80(минуя frontend), логaccess_docs.log.location = /healthz— встроенный healthcheck reverse-proxy, возвращает200 OK.location /— общий фронт, проксирование наhttp://frontend:3000.limit_req_status 429+error_page 429 = @ratelimit— кастомный ответ при превышении лимита с заголовкомRetry-After: 60.
Полный конфиг — в шаблоне поставки (devops/deployment-templates/nginx/config/conf.d/lk.1dh.ru.conf), его надо адаптировать под фактический домен заказчика.
Обратите внимание: backend проксируется не напрямую, а через frontend (http://frontend:3000). Frontend выполняет дополнительную обработку (server-side rendering, переадресацию авторизации) и сам обращается к backend:80 внутри dh_network.
Виртуальный сервер обмена (exchange)
Файл conf.d/exchange.<your-domain>.conf обслуживает домен exchange API и проксирует напрямую на backend (без frontend). Ключевые отличия от lk-сервера:
add_header Strict-Transport-Security ...; X-Content-Type-Options nosniff; X-Frame-Options DENY; X-XSS-Protection 1; mode=block— полный набор security headers по умолчанию (на lk эти заголовки в шаблоне закомментированы и включаются опционально).location ^~ /api/auth/→http://backend:80/api/auth/— авторизация напрямую, без frontend.location ^~ /api/exchange/→http://backend:80/api/exchange/— основные эндпоинты обмена.location /→return 404;— ничего, кроме/api/auth/и/api/exchange/, на этом домене не отдаётся.
Назначение раздельного домена для обмена:
- упростить настройку клиентских адаптеров (отдельный URL без необходимости знать структуру личного кабинета);
- позволить отдельную сетевую политику для трафика обмена (например, разрешить доступ интегрируемым системам по белому списку IP только к этому домену);
- ограничить площадь поверхности атаки — на
exchange.<domain>нет ни фронта, ни админских эндпоинтов.
Reverse-proxy на pgAdmin и RabbitMQ Management
Файлы conf.d/pg-admin.conf и conf.d/rmq-admin.conf устроены одинаково: слушают отдельный порт хоста (15432 и 15672), терминируют TLS, проксируют запросы на соответствующий сервис в dh_network с поддержкой WebSocket.
Особенности:
listen 15432 ssl default_server; server_name _;— принимают любойHost(по сути «свой собственный» виртуальный сервер на каждом порту).- Используют общий серверный сертификат
server.crt/server.key, отдельные сертификаты под админские порты не нужны. proxy_connect_timeout 300; proxy_send_timeout 300; proxy_read_timeout 300;— увеличенные таймауты под длительные операции pgAdmin (восстановление, экспорт).proxy_http_version 1.1+Upgrade $http_upgrade+Connection "upgrade"— поддержка WebSocket (требуется живым UI для обновления статистики).add_header X-Frame-Options "SAMEORIGIN"— смягчённый по сравнению сDENY(нужно для встроенных iframe в pgAdmin).
Эти эндпоинты — для администраторов, не для интегрируемых систем. На продуктивных стендах их доступ часто дополнительно ограничивается на сетевом firewall (разрешён только из VPN администраторов или из административной подсети).
Подстановка имён доменов
При установке шаблоны конфигов в conf.d/*.conf нужно адаптировать под фактические домена заказчика — в дефолтной поставке они идут с заглушками lk.1dh.ru / exchange.1dh.ru:
Также проверить и поправить пути к сертификатам в ssl_certificate / ssl_certificate_key.
После правки — пересоздать контейнер nginx:
Проверка и диагностика
Проверка корректности конфигурации без рестарта:
Применить обновлённый конфиг без полного рестарта (graceful reload):
Мониторинг сразу всех логов nginx (удобно для общего наблюдения):
Общий access-лог:
Общий error-лог:
Раздельные access-логи по виртуальным серверам — каждый можно смотреть отдельно. access_api.log — обращения к /api/* на личном кабинете:
access_auth.log — обращения к /api/auth/*:
access_auth_session.log — обращения к /api/auth/session*:
access_docs.log — обращения к документации backend:
access_exchange_log.log — обращения к exchange API:
access_log_80.log — запросы на порт 80 до редиректа:
access_log_15432.log — обращения к pgAdmin / RabbitMQ Management:
Что дальше
- Настройка безопасности — выпуск сертификатов через Let's Encrypt или self-signed, настройка mTLS, security headers.
- Production настройка — финальный чек-лист готовности промышленного стенда.
- Быстрый старт / п. 4.8 «Nginx» — пошаговая установка блока nginx при первичном развертывании.
- Диагностика / Анализ логов — формат логов и работа с ними.