Доступ участников к шине¶
Шина гетерогенна (event-bus-concept.md, разделы 1, 3): участники разнородны и часть из них внешние. Поэтому у шины два класса подключения с разной обвязкой.
Две сети, два класса участников¶
| Класс | Кто | Как подключается | Транспорт |
|---|---|---|---|
| Свои (on-box) | сервисы Coolify на той же машине (n8n, боты, Go/Python-сервисы, мост) | общая Docker-сеть event-bus |
nats://nats:4222 |
| Внешние | чужие API, другие машины/стеки | публичный домен Coolify | wss://<домен> (Traefik → ws 8080) |
Хранилища движка (postgres, redis) и сам inngest — на сети internal,
в шину и наружу не светятся. Движок — участник через мост, не напрямую.
Свои участники (общая сеть)¶
Шина владеет сетью event-bus (объявлена в stacks/bus/docker-compose.yml). Чтобы свой
сервис увидел nats:4222 по DNS, он подключается к той же сети. В его compose:
services:
my-service:
networks: [event-bus]
environment:
NATS_URL: nats://nats:4222
networks:
event-bus:
external: true # сеть создаёт стек шины, мы только присоединяемся
В Coolify это же делается тумблером «подключить к предопределённой сети» для ресурса. Публичный эндпойнт таким участникам не нужен.
Внешние участники (wss через Traefik)¶
Сырой порт 4222 наружу не выставляется. Внешние ходят по NATS WebSocket:
- Traefik (proxy Coolify) терминирует TLS на 443 и проксирует на ws-листенер
NATS (
websocket { port: 8080 }, см.stacks/bus/nats/nats-server.conf). - В Coolify сервису
natsназначается домен на порт 8080 → Let's Encrypt выдаёт сертификат автоматически. - Внешний клиент подключается на
wss://<домен>(клиенты NATS для Go/JS/Python умеют WebSocket-транспорт).
Назначать домен можно — авторизация шины включена (ниже), поэтому публичный ws не открыт на запись без кред.
Почему не обратный прокси (Caddy/Traefik) для авторизации шины: прокси видит только ws/TCP-поток и не понимает NATS-протокол — он не может применить права на subject'ы и не различает участников. Авторизация шины обязана жить внутри NATS. Прокси уместен только для HTTP-дашбордов (Inngest/мониторинг).
Авторизация (включена)¶
Модель — общие users с правами на subject'ы (зафиксировано, #10). Конфиг
— в stacks/bus/nats/nats-server.conf:
- Внутренние (мост, ops, smoke-тест) — пользователь
internalс полным доступом, пароль изNATS_INTERNAL_PASSWORD(Infisical).no_auth_userНЕ задан: раз ws публичный, креды обязаны предъявлять все, иначе любой подключится без пароля. - Внешние — каждый со своими кредами (
user/password) и allow-list на subject'ы. Это «контракт как ворота» (раздел 7) в рантайме: участник физически пишет/читает только заявленные в контракте subject'ы.
Пароли — через env-интерполяцию NATS ($VAR), значения из Infisical
(secrets.md). В nats-server.conf — только имена переменных.
Гранулярность: остановились на users (проще, достаточно для нескольких
участников). Переход на accounts (изоляция неймспейсов) — когда появится
недоверенная сторона; отдельным решением, не сейчас.
Онбординг внешнего участника (по контракту, раздел 9)¶
- PR в
contracts/asyncapi.yaml: какие subject'ы публикует/потребляет. - Завести креды участника (значение — в Infisical, имя — в
secrets.md). - Добавить юзера с allow-list на эти subject'ы в
nats-server.conf. - Передать участнику
wss://<домен>+ креды. - Отразить в каталоге зависимостей (когда он появится, раздел 10).
Удаление — зеркально: убрать юзера, отозвать креды, PR в контракты, чистка осиротевших consumer'ов (раздел 9).