Разделы документации
Архитектура
Из каких контейнеров состоит инсталляция 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_BACKEND—postgres, при любом другом сервисы не запускаются. - 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: без
него учётные данные коннекторов и ключи моделей из резервной копии прочитать
нельзя — см. «Безопасность».