MAATRIX / Блог / LibreChat на сервере: частые ошибки и решения

LibreChat на сервере: частые ошибки и решения

LibreChat на сервере: частые ошибки и решения

MAATRIX

На ноутбуке LibreChat поднимается одной командой, а на сервере ведёт себя иначе: chat-mongodb умирает через секунду после старта, после docker compose down -v всех разлогинило и сохранённые ключи перестали расшифровываться, а описанный в librechat.yaml эндпоинт не появляется в списке моделей. Эти ошибки LibreChat повторяются от установки к установке и опознаются по одной строке в логе. Ниже — шесть узлов, где ломается чаще всего: симптом, причина, команда, правка.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Как устроен LibreChat и кто именно сломался

LibreChat выглядит как одно приложение, но docker compose up -d поднимает шесть сервисов. Чинить надо не «LibreChat», а тот контейнер, чей лог ругается.

СервисКонтейнерОбраз в ветке 0.8За что отвечает
apiLibreChatregistry.librechat.ai/danny-avila/librechat-devсам чат, порт 3080
mongodbchat-mongodbmongo:8.0.20диалоги, пользователи, ключи
meilisearchchat-meilisearchgetmeili/meilisearch:v1.35.1поиск по истории
vectordbvectordbpgvector/pgvector:0.8.0-pg15-trixieэмбеддинги файлов
rag_apirag_apilibrechat-rag-api-dev-liteразбор файлов
admin-paneladmin-panellibrechat-admin-panelадминка, порт 3000

Старые мануалы ломает переезд реестра: ghcr.io/danny-avila/... уже не тянется, актуальный адрес — registry.librechat.ai, а latest означает ветку разработки. Разбор начинается с двух команд из каталога с docker-compose.yml:

cd /opt/LibreChat
docker compose ps -a --format "table {{.Service}}\t{{.Status}}"
docker compose logs --tail 200 api | grep -iE "error|warn|\[credentials\]"

Флаг -a обязателен: без него упавшие контейнеры не попадут в вывод. Restarting (1) — падение на старте, Exited (137) — OOM, Exited (132) — SIGILL, недопустимая инструкция процессора.

Версию смотрите изнутри, тег latest ни о чём не говорит: docker compose exec api grep '"version"' /app/package.json. Последний стабильный релиз — v0.8.7 от 24 июня 2026 года.

Стек не поднимается: UID, AVX, права и OOM

Пустые UID и GID. У сервисов api, mongodb и meilisearch стоит user: "${UID}:${GID}". Шелл эти переменные не экспортирует, и без них в .env Compose предупреждает:

WARN[0000] The "UID" variable is not set. Defaulting to a blank string.

Дальше демон отказывается запускать контейнер от пользователя : — ошибка вида unable to find user : no matching entries in passwd file. Лечение в две строки:

echo "UID=$(id -u)" >> .env
echo "GID=$(id -g)" >> .env

Права на каталог базы. Данные MongoDB лежат в бинд-маунте ./data-node:/data/db. Если каталог создался от root, а контейнер стартует от вашего UID, mongod падает:

DBException in initAndListen, terminating
IllegalOperation: Attempted to create a lock file on a read-only directory: /data/db

Лечится через sudo chown -R $(id -u):$(id -g) data-node meili_data_v1.35.1 uploads images logs.

AVX и Exited (132). С версии 5.0 MongoDB требует инструкций AVX, а в комплекте идёт mongo:8.0.20. Если гипервизор отдаёт гостю обобщённую модель процессора вроде kvm64, AVX туда не входит, и контейнер умирает мгновенно:

WARNING: MongoDB 5.0+ requires a CPU with AVX support, and your current system does not appear to have that!

Проверка: grep -o -m1 -w avx /proc/cpuinfo, пустой вывод — AVX нет. Обходной путь описан в самом репозитории: сохраните docker-compose.override.yml.example как docker-compose.override.yaml и раскомментируйте секцию mongodb: image: mongo:4.4.18. Минус называю прямо: 4.4 снята с поддержки, это подпорка, а не решение.

OOM. На 2 ГБ ядро начинает отстреливать контейнеры, чаще всего chat-meilisearch, и вы получаете Exited (137) без объяснений в логах приложения. Смотреть надо в ядро: journalctl -k --since "1 hour ago" | grep -i "out of memory". Вдобавок MongoDB забирает под кэш WiredTiger половину от «RAM минус 1 ГБ» — полтора гигабайта на машине с четырьмя; потолок задаётся через command: mongod --noauth --wiredTigerCacheSizeGB 0.5.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Всех разлогинило и ключи перестали расшифровываться

В ветке 0.8 секреты работают не так, как описано в старых руководствах. Четыре значения — CREDS_KEY, CREDS_IV, JWT_SECRET, JWT_REFRESH_SECRET — теперь можно не задавать: приложение сгенерирует их само и сохранит в /app/data/.env.temp — это путь внутри именованного тома librechat-data. В логе при старте:

[credentials] Generated temporary credentials for CREDS_KEY, CREDS_IV, JWT_SECRET, JWT_REFRESH_SECRET.
They are stored in /app/data/.env.temp; configure permanent values before production use.

Пока том жив, всё работает, но docker compose down -v сносит именованные тома, а ./data-node с базой — бинд-маунт, он остаётся. Итог: база на месте, секреты новые. Всех выкинуло на форму входа, а API-ключи, введённые пользователями в интерфейсе, зашифрованы старым CREDS_KEY и больше не читаются. LibreChat хранит в MongoDB отпечатки секретов и сверяет их при каждом запуске:

[credentials] Active fingerprints for CREDS_KEY, CREDS_IV do not match the database credential record.
Existing encrypted records or JWTs may require the previous values. Do not overwrite the database marker;
migrate the affected records and rotate all credentials together.

Увидели эту строку — не перезаводите ключи наугад: либо возвращаете прежние значения из сохранённого .env.temp, либо принимаете потерю осознанно, пользователи вводят ключи заново, диалоги при этом целы.

Отдельно: старые дефолты из .env.example внесены в чёрный список — [credentials] JWT_SECRET uses a retired default value. и отказ стартовать. Правильный порядок: задать все четыре значения до первого запуска, CREDS_KEY ровно 64 hex-символа, CREDS_IV ровно 32.

{
  echo "CREDS_KEY=$(openssl rand -hex 32)"
  echo "CREDS_IV=$(openssl rand -hex 16)"
  echo "JWT_SECRET=$(openssl rand -hex 32)"
  echo "JWT_REFRESH_SECRET=$(openssl rand -hex 32)"
} >> .env

Сразу положите эти строки в менеджер паролей: восстановить их неоткуда. Логика та же, что с солью в LiteLLM, который не видит API-ключи.

Вход, HTTPS и обратный прокси: 413 и обрыв стрима

Вход по кругу. Логин проходит, страница перезагружается — и снова форма входа. Причина в куках: LibreChat выставляет флаг Secure по эвристике из NODE_ENV и DOMAIN_SERVER, а браузер такие куки по обычному HTTP выбрасывает. Работаете по IP без сертификата — поставьте SESSION_COOKIE_SECURE=false, но только на время отладки. Заодно впишите настоящие DOMAIN_CLIENT и DOMAIN_SERVER вместо дефолтного http://localhost:3080: иначе сломаются письма подтверждения и OAuth-редиректы.

413 при загрузке файла. Во встроенном конфиге Nginx из репозитория стоит client_max_body_size 25M;, а свой прокси вы ставите с дефолтом в 1 МБ — и любой PDF получает 413 Request Entity Too Large. Лимит поднимается в двух местах: в Nginx и в librechat.yaml через fileConfig.serverFileSizeLimit.

Ответ приходит целиком в конце или обрывается на минуте. Классика: Nginx буферизует поток и режет соединение по proxy_read_timeout в 60 секунд. Минимальный рабочий блок:

location / {
    proxy_pass http://127.0.0.1:3080;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_buffering off;
    proxy_read_timeout 600s;
    client_max_body_size 100M;
}

Переменную TRUST_PROXY=1 при этом не трогайте: со значением 0 все запросы выглядят пришедшими с адреса прокси, и рейт-лимиты начинают блокировать пользователей пачками.

librechat.yaml не подхватился, модели не появились

Симптом: вы описали кастомный эндпоинт, перезапустили стек, а в интерфейсе его нет. Разгадка обычно в первой строчке лога.

Custom config file missing or YAML format invalid.

Она значит одно: файла нет там, где LibreChat его искал. И это штатное поведение — в базовом docker-compose.yml файл librechat.yaml внутрь контейнера не монтируется вообще, монтирование есть только в deploy-compose.yml. Создайте рядом docker-compose.override.yaml:

services:
  api:
    volumes:
      - type: bind
        source: ./librechat.yaml
        target: /app/librechat.yaml

Имя важно: Compose подхватывает docker-compose.override.yml и .yaml, но не docker-compose.override.yml.example — а именно так называется шаблон в репозитории. Проверка: docker compose exec api head -5 /app/librechat.yaml.

Вторая причина — файл прочитан, но отклонён схемой: Invalid custom config file at /app/librechat.yaml: и дамп с unrecognized_keys. Схема строгая, один лишний ключ роняет весь конфиг, а не одну секцию. Обязательное поле version в актуальном примере конфигурации — 1.3.13. Локализовать помогает CONFIG_BYPASS_VALIDATION=true: LibreChat стартует с дефолтным конфигом и пишет, что проигнорировал.

Третья причина — ключ из переменной окружения. LibreChat разворачивает ${VAR} внутри librechat.yaml, но если переменной в окружении нет, подстановка не происходит и вы получаете Missing API Key for MyEndpoint. — в поле apiKey остался буквальный текст ${MY_API_KEY}. Проверяйте окружение контейнера, а не своего шелла: docker compose exec api printenv | grep -i api_key.

И про встроенные эндпоинты: в .env по умолчанию стоит OPENAI_API_KEY=user_provided, то же для ANTHROPIC_API_KEY и GOOGLE_KEY. Это рабочий режим, а не заглушка — каждый вводит свой ключ в интерфейсе. Нужен общий, впишите настоящее значение.

Файлы, поиск и локальные модели: rag_api, Meilisearch, Ollama

Загрузка файлов молча не работает. Ищите в логе api строку, которая появляется при старте:

RAG API is either not running or not reachable at http://rag_api:8000, you may experience errors with file uploads.

Подводный камень: в комплекте идёт образ librechat-rag-api-dev-lite — «лёгкий», без локальных моделей эмбеддингов, он только зовёт внешний API. Без EMBEDDINGS_PROVIDER=openai и RAG_OPENAI_API_KEY разбор файлов упадёт на 401 от провайдера. Свои эмбеддинги — это оверрайд с полным образом librechat-rag-api-dev:latest и лишняя пара гигабайт RAM.

Поиск не работает или роняет старт. В свежем .env.example стоит SEARCH=false: Meilisearch — самый прожорливый участник стека. Включили поиск, но не задали MEILI_MASTER_KEY — получите Meilisearch configuration is missing. При недоступном сервисе будет Meilisearch not available, а следом успокаивающее Meilisearch error, search will be disabled: чат продолжит работать без поиска. Имя тома — ./meili_data_v1.35.1, версия зашита в путь: апдейт движка не упрётся в несовместимый формат, индекс просто пересоберётся из MongoDB. Не нужен поиск — отключите контейнер в оверрайде:

services:
  meilisearch:
    profiles:
      - donotstart

Локальная модель не подключается. Адрес http://localhost:11434 внутри контейнера — это сам контейнер, а не хост. У api прописан extra_hosts: - "host.docker.internal:host-gateway", поэтому указывайте baseURL: 'http://host.docker.internal:11434/v1'. Со стороны Ollama снимите привязку к петле: sudo systemctl edit ollama.service, блок [Service] со строкой Environment="OLLAMA_HOST=0.0.0.0:11434", перезапуск. Поле apiKey пустым не оставляйте — впишите любую строку вроде 'ollama'.

Грабля версий 0.8 — защита от SSRF: для эндпоинтов с baseURL: 'user_provided', а также для Actions и удалённых MCP-серверов адреса в приватных сетях блокируются по умолчанию. Разрешение выдаётся точечно, парой «хост:порт»:

endpoints:
  allowedAddresses:
    - 'host.docker.internal:11434'
mcpSettings:
  allowedDomains:
    - 'host.docker.internal'

Расчёт под модель рядом на CPU. Наш замер на AMD EPYC 9554 (16 vCPU — 8 физических ядер плюс HT), Ollama 0.33.1, qwen2.5:7b в кванте Q4_K_M: 5,7 токена в секунду при num_thread 2, 7,6 при 4 и те же 7,6 при 8 — упирается в память, а не в процессор; при 32 потоках обвал до 0,35, в двадцать раз. qwen2.5:3b там же даёт 34,1 ток/с при 2,2 ГБ в памяти. Вывод: на CPU комфортно живёт модель класса 3B, чат для команды упирается в облачные API или в GPU. Подробнее — в разборе Open WebUI против LibreChat.

Какой сервер под LibreChat брать в MAATRIX

LibreChat сам модели не считает — он оркестрирует чужие API и хранит историю. Нагрузка идёт не на процессор, а на память: одновременно работают Node, MongoDB, Postgres, Python-сервис и, если включён поиск, Meilisearch.

Честный минимум: 2 vCPU, 4 ГБ RAM, 40 ГБ NVMe. Хватает на полный стек для команды из нескольких человек при SEARCH=false. На 2 ГБ полный набор контейнеров не живёт: ядро отстрелит их по OOM, и Exited (137) вы увидите раньше, чем успеете войти.

Комфортный вариант: 4 vCPU, 8 ГБ RAM, 80 ГБ NVMe. Здесь работают поиск по истории, локальные эмбеддинги на полном RAG API и запас под рост базы: MongoDB, Meilisearch и pgvector хранят одни данные в трёх формах.

Локация — Великобритания, Лондон. Российский IP отсекается провайдерами моделей на уровне адреса: OpenAI отвечает 403 unsupported_country_region_territory, Google для Gemini — User location is not supported for the API use, и перегенерация ключа не помогает. С британского адреса все трое отвечают штатно, а до Лондона от Москвы ближе, чем до Нью-Йорка. Если пользователи в основном за океаном, разумнее взять США.

Про установку честно. LibreChat в каталоге apps.maatrix.io пока нет — сервер приезжает чистым, с Ubuntu 24.04 или Debian, и стек вы разворачиваете руками по инструкции выше: git clone, cp .env.example .env, четыре секрета через openssl, UID и GID, оверрайд с librechat.yaml, docker compose up -d. Зато в каталоге есть готовые сборки соседей по задаче — Ollama, LiteLLM, AnythingLLM, Dify, Qdrant, n8n, Portainer: они ставятся автоматически при заказе, доступы появляются в кабинете. Оплата — картой российского банка, по СБП, криптой или токеном MAAT: зарубежная карта не нужна, хотя сервер стоит в Лондоне.

Из бэкапов снимайте две вещи: каталог ./data-node с базой и файл .env с четырьмя секретами. Первый без второго бесполезен.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Частые вопросы

После docker compose down -v всех разлогинило и ключи не расшифровываются. Можно вернуть?

Только если сохранились прежние CREDS_KEY и CREDS_IV. Флаг -v удаляет том librechat-data со сгенерированным .env.temp, а база в бинд-маунте ./data-node остаётся — отсюда расхождение отпечатков. Диалоги и учётки целы, потеряны только зашифрованные ключи пользователей.

Правлю librechat.yaml, а изменений нет. Что проверить?

Смонтирован ли файл вообще: в базовом docker-compose.yml его нет. Выполните docker compose exec api head -5 /app/librechat.yaml и поищите в логе Custom config file missing or YAML format invalid. — эта строка означает, что контейнер файла не видит.

Хватит ли 2 ГБ RAM?

Для полного стека из шести контейнеров — нет, память закончится на Meilisearch или MongoDB. Реалистичный минимум — 4 ГБ, комфортный — 8 ГБ. В 2 ГБ помещается только урезанный вариант: api и mongodb с SEARCH=false и отключённым RAG API, то есть без поиска и без загрузки файлов.

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.