MultiAgent никогда не распределяет запросы сам: на каждом сервере работает свой Nginx-контейнер agents-nginx, который MultiAgent разворачивает, настраивает и обновляет. Все приложения сервера — агенты, продукты, инструменты с веб-интерфейсом и произвольные сервисы — раздаются по подпапкам одного адреса: {база}/{слаг}/. Никаких отдельных доменов, поддоменов и ручных конфигов под каждое приложение: у сервера один адрес, и каждое приложение живёт в своей подпапке.
Как это работает
На каждом управляемом сервере MultiAgent поднимает один контейнер agents-nginx (образ nginx:alpine, сервис nginx). Контейнер ставится из вкладки Nginx страницы сервера: MultiAgent создаёт файлы конфигурации на сервере (загружаются по защищённому каналу), присоединяет контейнер к общей docker-сети и запускает его.
Конфигурация маршрутов собирается из базы MultiAgent автоматически: при каждом изменении (создали, изменили или удалили запись агента, продукта или инструмента, добавили или отредактировали ссылку или пользовательский маршрут, установили или удалили центральный вход, изменили порты) конфиг пересобирается и применяется сам. Применение не обрывает соединения: конфигурация проверяется и перезагружается внутри уже работающего веб-сервера, поэтому открытые страницы и живые чаты не рвутся (контейнер пересоздаётся только когда меняется его собственный файл настройки). Изменение адреса сервера (host или шаблона URL) тоже пересобирает маршруты и дополнительно синхронизирует настройки центрального входа. Установки показывают свои шаги в ленте прогресса, изменения записей применяются в фоне. Кнопка «Применить конфигурацию» во вкладке прогоняет то же обновление вручную — удобно, когда правку сделали прямо на сервере.
Источники маршрутов
Общая таблица маршрутов собирается автоматически из пяти источников:
- Агенты и продукты — каждая развёрнутая запись агента (включая продукты из каталога) автоматически даёт маршрут: появляется вместе с записью и исчезает с её удалением;
- Дополнительные ссылки агентов и продуктов — ссылка со вкладки «Ссылки» с указанным маршрутом получает свою подпапку, которая ведёт на выбранный порт сервера: появляется вместе со ссылкой и исчезает вместе с ней;
- Инструменты с веб-интерфейсом — инструмент, у шаблона которого объявлен веб-порт, получает маршрут автоматически (порт берётся из шаблона и обновляется при каждом развёртывании); без веб-порта инструмент остаётся на прямом адресе
http://{хост}:{порт}; - Центральный вход — производный маршрут с фиксированным слагом
auth(адрес{база}/auth/— страница входа): появляется вместе с установкой центрального входа на вкладке «Авторизация» и исчезает после его удаления; read-only, никогда не закрывается защитой и не имеет собственного переключателя; - Кастомные маршруты — единственный вид с ручным управлением: произвольный http(s)-адрес (не обязательно управляемый MultiAgent — служба на своём порту, локальный сервис, внешняя система), с редактированием, отключением и удалением.
Вкладка показывает все маршруты, отсортированные по слагу, с публичным адресом и целью для каждого; автоматические виды помечены «Managed by MultiAgent» и кликом ведут к исходной записи (клик по строке центрального входа открывает вкладку «Авторизация» страницы сервера).
Схема трафика
Трафик идёт так: http(s)://{хост сервера}/{слаг}/ → Nginx сервера → контейнер приложения во внутренней docker-сети ({имя контейнера}:{порт}). Приложения адресуются по именам контейнеров, поэтому публиковать порты наружу не нужно.
- Резолвинг на лету — конфиг использует внутренний резолвер и переменные адресов: Nginx стартует и работает независимо от того, какие приложения существуют. Неработающее, остановленное или ещё не развёрнутое приложение даёт ошибку только на своей подпапке, остальные маршруты продолжают работать;
- WebSocket и большие ответы — поддерживаются постоянные соединения (живые чаты агентов), длинные таймауты и безлимитный размер передаваемых данных;
- Заголовки — приложению передаются служебные данные о префиксе, хосте и схеме, поэтому чувствительные к префиксу приложения строят правильные абсолютные адреса; за внешним прокси приложения получают https-схему и исходный хост;
- Корень
/— отдаётся домашней страницей сервера, когда она установлена (см. ниже); без неё корень ведёт себя как обычная резервная страница.
Защита приложений (центральный вход)
Если на сервере установлен центральный вход (вкладка «Авторизация» страницы сервера, подробнее — на странице Серверы), защищённые маршруты пропускаются через него: посетитель один раз входит на странице входа {база}/auth/ и дальше открывает любое защищённое приложение сервера без повторного логина.
- Агенты и продукты закрыты «за центральным входом» по умолчанию — переключатель в карточке приложения позволяет открыть их снова. Инструменты с веб-интерфейсом и пользовательские маршруты защищаются по вашему выбору: переключатель «За центральным входом» на строке. Сам маршрут входа (
auth) никогда не закрывается; - Для защиты нужен HTTPS: она включается, только когда фронт работает по HTTPS — локальный сертификат и порт HTTPS из вкладки Nginx либо шаблон адреса вида
https://{база}/{слаг}, когда TLS снимает верхний обратный прокси. Иначе установленный центральный вход остаётся неактивным; - Машинные пути не закрываются:
/{слаг}/api/…и/{слаг}/svelteChatHubработают без входа (у приложений там своя авторизация — JWT или API-ключ), а прямой доступ по адресуhost:portв обход nginx сохраняет собственный вход приложения. Остановленный центральный вход закрывает только свои защищённые маршруты — остальные подпапки продолжают работать; - Личность и секрет: защищённое приложение получает заголовки личности посетителя (имя, группы, email), а агенты и продукты дополнительно — секрет
X-SSO-Token, по которому убеждаются, что запрос пришёл через nginx (сверка сSSO_PROXY_TOKENв переменных окружения агента); инструментам и пользовательским маршрутам секрет не передаётся.
Пространство имён и зарезервированные префиксы
Слаг первого уровня — единое пространство имён на каждый сервер, общее для агентов, продуктов, инструментов и пользовательских маршрутов: один и тот же слаг может существовать на разных серверах, но на одном сервере его можно занять только один раз. Слаги — только строчные буквы, цифры и дефисы ([a-z0-9-]+).
Служебные пути MultiAgent зарезервированы и не могут стать слагами: api, v1, swagger, servers, agents, tools, workspaces, analytics, accounts, data, а также слаг auth — он зарезервирован на каждом сервере независимо от того, установлен ли центральный вход, и принадлежит его маршруту. Агента с именем api, servers или auth создать нельзя — форма подсветит это сразу, а сервер отклонит запись.
Кастомные маршруты
Кастомный маршрут направляет подпапку на любой абсолютный http(s)-адрес, доступный с сервера: служба на своём порту, локальное приложение, внешняя система. Для создания нужны имя, слаг по правилам пространства имён и цель — абсолютный адрес вида http(s)://… (значение без схемы отклоняется).
- Каждое изменение (создание, редактирование, включение, отключение, удаление) сразу пересобирает и применяет конфиг;
- Отключённый маршрут убирает свою подпапку — она начинает отвечать ошибкой 404, запись остаётся в таблице;
- Удаление освобождает слаг для любого вида — другой агент, инструмент или маршрут сможет его занять;
- Если у цели есть собственный базовый путь (например,
http://host/wiki), он подставляется вместо слага:/{слаг}/docs/pageдостигает/wiki/docs/page.
Сертификаты
Сертификаты управляются из того же вкладки Nginx — три вида:
- Самоподписанный — генерируется MultiAgent и служит резервным сертификатом; его можно скачать как файл
.crtи импортировать в доверенные сертификаты системы; - Собственная пара PEM — вставляется или загружается; цепочка и ключ проверяются до записи (ключ должен совпадать с сертификатом, просроченный отклоняется с предупреждением);
- Let’s Encrypt — бесплатные сертификаты через сам Nginx (проверка владения доменом по протоколу ACME): тестовая (staging) и рабочая площадка, один запрос за раз, домен должен указывать на сервер.
Ключевые материалы хранятся только на сервере (папка ssl/{домен}/: полная цепочка + приватный ключ) и монтируются в контейнер только для чтения — в базе MultiAgent лишь метаданные. Каждое обновление конфигурации продлевает сертификаты, истекающие в течение 30 дней (самоподписанные перегенерируются, Let’s Encrypt запрашивается заново), плюс есть ручное продление по строке. HTTPS-порт опционален: пока он пуст, публикуется только HTTP, и сертификаты хранятся, но не раздаются. Успешный запрос Let’s Encrypt при пустом порте сам включает его (443) — сертификат сразу обслуживается, а выбранный вами порт или явно выключенный HTTPS не переопределяются. В локальном режиме (свой сертификат и порт HTTPS) весь HTTP, включая подпапки маршрутов, перенаправляется на HTTPS — исключение только /.well-known/acme-challenge/, по которому продолжает отвечать сам Nginx. Когда TLS снимает верхний обратный прокси (шаблон адреса https://{база}/{слаг}), HTTP-слушатель продолжает раздавать маршруты — браузер уже работает по HTTPS у прокси.
Сам MultiAgent в подпапке
MultiAgent — и сам такое приложение: его можно разместить не только в корне домена, но и в любой подпапке (ваш-домен/multiagent), причём тем же самым образом и без пересборки. Никаких настроек внутри программы для этого не нужно — MultiAgent понимает, где он находится, по адресу запроса. Есть два способа сказать ему об этом.
Через переменную окружения — когда верхний прокси передаёт путь как есть, без изменений. Достаточно добавить при запуске:
- MULTIAGENT_BASE_PATH=/multiagent
MultiAgent сам отрежет префикс и один раз перенаправит запросы, набранные без него, в адрес с подпапкой. Путь проверки сертификата (/.well-known/) остаётся в корне — так его выпуск продолжает работать. Пустое значение означает работу в корне домена.
Через заголовок прокси — когда подпапкой управляет сам прокси: в его настройках к обычному проксированию добавляется одна строка — proxy_set_header X-Forwarded-Prefix /multiagent;. Тогда MultiAgent читает подпапку из заголовка и ничего не перенаправляет — маршрутизацией полностью владеет прокси.
При развёртывании на управляемом сервере ничего из этого не требуется: конфигурация, которую MultiAgent сам для него собирает, уже передаёт подпапку и нужный заголовок. В одном домене можно держать несколько экземпляров в разных подпапках: у каждого своя база и свои ключи, поэтому вход в одном никогда не действует в другом, а в браузере у каждой подпапки своё отдельное состояние.
Домашняя страница сервера
Корень / Nginx отдаёт домашнюю страницу сервера, когда она установлена (вкладка «Домашняя страница» страницы сервера; требуется установленный Nginx). Это статичная панель карточек, которую MultiAgent сам собирает из своей базы и загружает на сервер: по карточке на каждого агента, продукт и инструмент с адресом — с реальными логотипами проектов, плюс карточка Git (когда установлен Forgejo) и карточка «Выйти». Отдельного входа у страницы нет: при включённом центральном входе она закрыта вместе с остальными приложениями. Подробнее — на странице Домашняя страница сервера.
Подпапки приложений всегда имеют приоритет над путями страницы: агент со слагом settings будет отдан по /settings/, а сама домашняя страница продолжит работать в корне. Если Nginx остановлен, страдает только корень — подпапки приложений продолжают работать.
Публичный адрес
Канонический публичный адрес каждого приложения — {база}/{слаг}/. База выводится в одном месте: это база из шаблона адреса агентов, когда он имеет вид {база}/{slug} (так за проксированным сервером получаются https-ссылки без собственного сертификата); иначе — http(s)://{хост сервера}[:{порт nginx}]. Схема следует одному правилу: любой сертификат + включённый HTTPS-порт → https, иначе http. Прямой доступ http://{хост}:{порт} остаётся запасным путём и помечен «direct access» в интерфейсе.