> ## Documentation Index
> Fetch the complete documentation index at: https://omniflow-vpn.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Обратный прокси

> Используйте Caddy, Traefik, Nginx или другой совместимый ingress

Omniflow не требует обратного прокси, не поставляет его в комплекте и не запускает автоматически. Операторы могут выбрать Caddy, Traefik, Nginx, HAProxy или управляемый ingress.

Прокси должен обеспечивать TLS, сохранять идентификаторы запросов, применять ограничения на размер тела и корректно маршрутизировать трафик API, веба, вебхука Telegram и вебхуков провайдеров. Клиентские и административные маршруты обслуживаются одним и тем же веб-контейнером. Настраивайте заголовки доверенных прокси явно; никогда не доверяйте произвольному вводу в `X-Forwarded-For`.

## Поддерживаемые примеры

Оба поддерживаются в рабочем состоянии, и оба проверяются в CI.

| Прокси | Файлы |
| - | - |
| Caddy | `deploy/proxies/Caddyfile` |
| Traefik | `deploy/proxies/traefik.yaml`, `traefik-dynamic.yaml`, `traefik.compose.yaml` |

Пример для Traefik запускается как оверлей compose:

```bash theme={null}
ACME_EMAIL=ops@example.com \
WEB_DOMAIN=app.example.com \
API_DOMAIN=api.example.com \
BOT_WEBHOOK_DOMAIN=bot.example.com \
docker compose -f compose.yaml -f deploy/proxies/traefik.compose.yaml up -d
```

Оверлей также прекращает публикацию портов API и веба на хосте, поскольку перед ними стоит прокси.

## Хосты

| Хост | Что обслуживает |
| - | - |
| `WEB_DOMAIN` | Единое приложение для клиентов и администраторов; рабочее пространство администратора остаётся под `/admin`. **А также `/v1`**, направленный в API — см. ниже |
| `API_DOMAIN` | API на Go, включая вебхуки провайдеров по `/v1/payments/webhooks/{provider}` |
| `BOT_WEBHOOK_DOMAIN` | Только `POST /telegram/webhook`, когда бот работает в режиме вебхука |

`BOT_WEBHOOK_DOMAIN` может совпадать с хостом API. Держать его отдельно аккуратнее, но не обязательно.

## `/v1` обязан обслуживаться на веб-хосте

Обе панели обращаются к API на **том же origin**. Общий браузерный клиент держит базовый URL равным
`""` (`packages/api-client/src/fetcher.ts`), и `setBaseUrl` никто не вызывает, поэтому запрос из
панели идёт на веб-хост и ожидает, что ответит API. Поэтому оба примера направляют `/v1` на
`WEB_DOMAIN` в контейнер API — с тем же ограничением тела запроса и той же блокировкой операционных
эндпоинтов, что и на публичном хосте API.

Это не удобство. Именно это оставляет сессионную куку first-party, а значит позволяет ей быть
`SameSite=Lax` и `HttpOnly` вообще без CORS. Публиковать API панели на другом origin означало бы
`SameSite=None`, куку `Secure`, отправляемую при кросс-сайтовых запросах, и список разрешённых
origin с передачей учётных данных — три подвижные части вокруг операторской сессии вместо одной.

> [!WARNING]
>
> Прокси, который обслуживает `WEB_DOMAIN`, но не направляет `/v1`, даёт панель, которая выглядит
> совершенно здоровой и не умеет ничего. Страницы отрисовываются, анонимного посетителя по-прежнему
> перенаправляет на вход, а форма входа сообщает *«Не удалось войти. Попробуйте ещё раз.»* — потому
> что запрос дошёл до Next.js, где маршрута `/v1` нет, а не до API. Если вы пишете свою конфигурацию
> прокси, это правило нужно перенести в неё.

`API_DOMAIN` всё равно стоит публиковать: вебхуки провайдеров, bearer-поверхность `/v1/admin` и
вебхук Telegram вызывают системы, а не браузер. Установка на одном хосте, обслуживающая только
`WEB_DOMAIN`, работает для обеих панелей, но ей некуда направить платёжного провайдера.

## Не публикуйте операционные эндпоинты

`/metrics` и `/readyz` описывают внутреннее устройство установки: здоровье зависимостей, глубину очереди, классификации платежей. Оба примера возвращают для них 404 на публичном хосте API. Собирайте их по внутренней сети или закройте собственной аутентификацией.

`/livez` безопасно публиковать — он сообщает только о том, что процесс запущен.

## Ограничения на размер тела

| Маршрут | Ограничение | Почему |
| - | - | - |
| API | 2 МБ | Приложение уже ограничивает тела JSON одним мегабайтом; ограничение на прокси — внешний рубеж |
| Вебхук Telegram | 1 МБ | Обновления Telegram невелики, и бот тоже их ограничивает |

## Не переписывайте тела запросов

Подписи вебхуков провайдеров вычисляются по точным байтам, которые прислал провайдер. Прокси, который перекодирует, форматирует или нормализует тело JSON, делает недействительными все подписи, и Omniflow справедливо отклонит результат как непроверенный. Если после изменения прокси вебхуки начали не проходить проверку, это первое, что нужно проверить.

## Журналы доступа

Журнал доступа записывает пути запросов, а ссылка на подписку — это путь запроса. Именно поэтому в примере для Traefik журналирование доступа по умолчанию выключено. Если он вам нужен, примените фильтр путей, который вы проверили.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.