Разделы документации
Платформа

Архитектура

Из каких контейнеров состоит инсталляция Charo, как между ними проходят данные, что расходует ресурсы и что нужно резервировать.

Компоненты

Charo — одна программа. При установке она раскладывается на контейнеры Docker Compose: каждый выполняет свою часть работы и общается с остальными по внутренней сети.

КомпонентНазначение
Обратный прокси (Caddy)единственная входная точка HTTP: разводит веб-интерфейс, /api, /scim и /mcp, ограничивает тело запроса 512 МБ
Веб-интерфейсчат и админка
API-сервервесь HTTP продукта: чат, поиск, админка, приём документов через API, SCIM
Фоновый воркериндексация, синхронизация прав, очистка удалённых документов, подготовка моделей
Исполнитель коннекторовобращается к внешним системам и отдаёт загруженные документы воркеру
MCP-серверотдаёт поиск по вашей базе знаний внешним MCP-клиентам по адресу /mcp
Сервер моделейлокальный расчёт векторов (ONNX) для индексации и запросов, а также распознавание текста на сканах и изображениях
PostgreSQLпользователи, чаты, настройки, метаданные документов и содержимое загруженных файлов
Valkeyочереди фоновых задач, кэш и сессии входа
Qdrantвекторы, текст фрагментов и полнотекстовый (BM25) индекс
Миграции схемыодноразовый контейнер: накатывает схему базы данных до старта остальных

Несколько уточнений, которые обычно всплывают при первом знакомстве со стеком:

  • Файлы хранятся в PostgreSQL (large objects). Отдельного файлового хранилища в поставке нет, S3-совместимое подключить нельзя: единственное допустимое значение FILE_STORE_BACKENDpostgres, при любом другом сервисы не запускаются.
  • Valkey, а не Redis. Это свободная и совместимая с Redis реализация под лицензией BSD-3-Clause; версии Redis начиная с 7.4 распространяются на условиях, несовместимых с поставкой в составе продукта. Переменные окружения по историческим причинам по-прежнему называются REDIS_HOST и REDIS_PORT. Valkey работает с записью журнала на диск, поэтому перезапуск не теряет очередь задач.
  • Сервер моделей один. Приоритет реализован внутри процесса: запросы пользователей вытесняют фоновую индексацию, поэтому поиск не замедляется во время переиндексации. Развести индексацию на отдельный сервер можно переменными INDEXING_MODEL_SERVER_HOST и INDEXING_MODEL_SERVER_PORT, но по умолчанию сервер один.
  • Фоновый воркер — один процесс, а не набор контейнеров. Внутри он разбирает 20 именованных очередей: загрузка документов, их обработка, синхронизация прав и групп, очистка, обслуживание моделей, выгрузка истории запросов.
  • Отдельного поискового движка нет. Qdrant держит и векторы, и полнотекстовый индекс.
  • Интерпретатора кода в продукте нет. Контейнер-песочница не разворачивается, соответствующие инструменты выключены и скрыты в интерфейсе.

Отправка трассировок включается переменной OTEL_EXPORTER_OTLP_ENDPOINT: если она не задана, экспорт не работает вовсе, а если задана — трассы уходят в ваш OTLP-коллектор.

Все компоненты отдают метрики в формате Prometheus на GET /metrics. Собственной системы мониторинга в поставке нет — предполагается, что их соберёт ваша. Через обратный прокси эти адреса намеренно не проксируются.

Как проходят данные

Индексация. Воркер поручает исполнителю коннекторов забрать новые и изменённые документы из источника, складывает их пакетами в файловое хранилище (то есть в PostgreSQL) и уже оттуда ведёт по конвейеру: разбиение на фрагменты → эмбеддинги → запись векторов и текста фрагментов в Qdrant → обновление метаданных в PostgreSQL. Сбой на одном документе не роняет весь пакет. Подробно по шагам — «Потоки данных».

Ответ на вопрос. API-сервер считает вектор запроса и отправляет в Qdrant два подзапроса — по векторной близости и по ключевым словам (BM25); Qdrant сам объединяет их ранговым слиянием. Полнотекстовая часть настроена на русскую морфологию. Найденные фрагменты фильтруются по правам пользователя, собранный контекст уходит в языковую модель, ответ со ссылками на источники возвращается в веб-интерфейс.

Внешние клиенты. Тот же поиск доступен по протоколу MCP: внешний клиент подключается к /mcp и получает те же результаты, что и чат.

Сеть и порты

Наружу открывается только обратный прокси: порт 80, а если при установке указан домен — ещё и 443 с автоматически выпущенным сертификатом. Служебные порты остальных контейнеров (база данных, Qdrant, Valkey, сервер моделей) по умолчанию публикуются на петлевом интерфейсе 127.0.0.1 и извне недоступны.

Не расширяйте эту привязку без необходимости. Открытый наружу PostgreSQL с паролем по умолчанию — самый быстрый способ потерять базу; для доступа с другой машины пользуйтесь SSH-туннелем.

Требования к ресурсам

Минимальные конфигурации, проверки установщика и совместимость по операционным системам — на странице «Требования». Что именно расходует ресурсы:

  • Память. Qdrant держит в оперативной памяти граф поиска (HNSW) и сжатые до 8 бит копии векторов, а сами векторы — на диске; полнотекстовый индекс по умолчанию тоже в памяти и переносится на диск переменной QDRANT_SPARSE_ON_DISK. Потребление растёт с числом фрагментов, но медленнее, чем полный объём эмбеддингов. Отдельно память нужна серверу моделей: под выбранную модель эмбеддингов и — когда в индексацию попадают сканы — ещё около 600 МБ под распознавание текста.
  • CPU. Основная длительная нагрузка — расчёт эмбеддингов и распознавание текста при индексации. Графический ускоритель не обязателен.
  • Диск. Растёт PostgreSQL (метаданные, содержимое загруженных файлов и промежуточные пакеты документов) и Qdrant; отдельно место занимает кэш скачанных моделей. Переполнение диска останавливает индексацию.

Ограничений по памяти и процессору на контейнерах не задано — стек забирает то, что есть на машине.

Масштабирование

  • Вертикально (первый шаг): больше оперативной памяти для Qdrant, больше процессорных ядер для сервера моделей.
  • Вынос компонентов: PostgreSQL, Qdrant и сервер моделей можно перенести на отдельные машины — адреса задаются переменными окружения (POSTGRES_HOST, QDRANT_HOST, MODEL_SERVER_HOST).
  • Разделение нагрузки: индексацию можно увести на второй сервер моделей переменными INDEXING_MODEL_SERVER_*.

Для инсталляций на сотни активных пользователей напишите в поддержку — поможем подобрать конфигурацию.

Отказоустойчивость и резервные копии

Состояние системы хранится в томах Docker:

ТомЧто в нём
Данные PostgreSQLпользователи, чаты, настройки, метаданные и содержимое файлов
Данные Qdrantвекторы и полнотекстовый индекс
Журнал Valkeyочередь фоновых задач в работе
Кэш моделейскачанные модели эмбеддингов
Данные и конфигурация Caddyвыпущенные сертификаты

Минимально достаточная резервная копия — том PostgreSQL: загруженные файлы уже внутри него, а векторный индекс восстанавливается переиндексацией. Копия вместе с томом Qdrant избавляет от долгой переиндексации при восстановлении.

Вместе с базой сохраните значение ENCRYPTION_KEY_SECRET из файла .env: без него учётные данные коннекторов и ключи моделей из резервной копии прочитать нельзя — см. «Безопасность».