В любой компании со временем накапливаются сотни внутренних файлов: должностные регламенты, инструкции, прайс-листы, коммерческие предложения, договоры и техническая документация. Поиск нужной информации вручную отнимает у сотрудников часы рабочего времени, а загрузка закрытых корпоративных файлов в публичные облачные сервисы вроде ChatGPT или Claude напрямую нарушает коммерческую тайну и закон 152-ФЗ «О персональных данных». AnythingLLM — это ведущая открытая платформа (более 35 000 звёзд на GitHub, лицензия MIT), объединяющая в одном легковесном контейнере полноценный RAG-конвейер (Retrieval-Augmented Generation): встроенный парсер документов (PDF, DOCX, XLSX, TXT, HTML), нативную векторную базу данных LanceDB, ролевой доступ для отделов и возможность встраивания чат-виджета на внутренний сайт компании. В этом практическом руководстве мы развернем стабильный релиз AnythingLLM v1.19.0 в Docker Compose на VDS, рассмотрим встроенный движок инференса Lemonade/llama.cpp, подключим локальную модель Ollama или экономичный API DeepSeek, настроим потоковый Nginx с SSL и организуем автоматический бэкап базы знаний.
1. Архитектура RAG в AnythingLLM: как работает поиск по документам без утечки данных
В отличие от стандартных чат-интерфейсов, которые передают в нейросеть только текст диалога, комплекс AnythingLLM реализует классический конвейер Retrieval-Augmented Generation (генерация с дополнением выборкой):
- Парсинг и извлечение сырого текста (Document Parsing). При загрузке файла платформа автоматически извлекает структурированный текст из PDF-файлов (включая многостраничные таблицы и сканы), документов Word (
.docx), электронных таблиц Excel/CSV, презентаций и веб-страниц. - Чанкование (Text Chunking & Splitting). Длинный текст нарезается на смысловые фрагменты фиксированного размера. В настройках AnythingLLM размер фрагментов измеряется в символах: по умолчанию размер чанка составляет 1000 символов с наложением (overlap) в 20 символов (что на русском и английском языках эквивалентно примерно 180–250 токенам). Это сохраняет семантическую непрерывность фраз на стыках абзацев и предотвращает разрыв определений.
- Векторизация (Embeddings). Каждый фрагмент пропускается через модель эмбеддингов (встроенную локальную модель Xenova на базе MiniLM, либо серверную Ollama с моделью nomic-embed-text / bge-m3), превращаясь в многомерный числовой вектор.
- Индексация во встроенной LanceDB. Полученные векторы сохраняются в бессерверной колоночной базе данных LanceDB. В отличие от тяжелых автономных баз данных, LanceDB работает непосредственно на диске VDS без отдельного фонового процесса, обеспечивая мгновенный поиск ближайших соседей (k-NN) с минимальным потреблением оперативной памяти.
- Семантический поиск и ответ (Similarity Search & Synthesis). Когда сотрудник задает вопрос («Каков порядок согласования командировочных расходов?»), система находит в LanceDB 3–5 наиболее релевантных фрагментов из документов компании, объединяет их в системный промпт и передает в языковую модель. В ответе нейросеть ссылается на конкретный пункт и страницу регламента.
💡 Почему встроенная LanceDB выгоднее внешних векторных СУБД для компактных VDS
Автономные векторные базы данных (например, распределенный Milvus со своими зависимостями от etcd и MinIO, либо standalone-демоны Qdrant и Weaviate) постоянно удерживают в оперативной памяти фоновый процесс и структуры HNSW-графов (базовый оверхед составляет от 500 МБ до 1.5 ГБ RAM даже в режиме простоя). AnythingLLM по умолчанию использует встроенный в ядро движок LanceDB на базе формата Apache Arrow: он не запускает отдельный сетевой сервис, сохраняет векторные индексы прямо в локальном каталоге storage/lancedb и задействует оперативную память только во время выполнения поискового запроса. Это позволяет комфортно запускать RAG-платформу даже на компактном сервере с 2–4 ГБ RAM.
2. Системные требования и выбор конфигурации VDS
Аппаратные требования к серверу зависят от выбранного режима инференса: встроенный локальный движок Lemonade/llama.cpp, внешняя Ollama на CPU или облачный API (DeepSeek, LiteLLM Proxy):
| Параметр | Режим API + Встроенная LanceDB | Режим Full Self-Hosted (с Ollama или Built-in LLM на CPU) |
|---|---|---|
| Процессор (vCPU) | 2 vCPU (2.4+ ГГц) |
4–8 vCPU (3.0+ ГГц с поддержкой AVX2) |
| Оперативная память | 2–4 ГБ RAM |
8–16 ГБ RAM (под квантованные модели Qwen2.5 / Llama 3) |
| Дисковая подсистема | 25–40 ГБ NVMe | 60–120 ГБ NVMe (хранение весов GGUF и кэша векторов) |
| Операционная система | Ubuntu 24.04 LTS / Debian 12 | Ubuntu 24.04 LTS (ядро 6.8+ с оптимизациями памяти) |
| Сетевой канал | от 100 Мбит/с | от 200 Мбит/с до 1 Гбит/с |
3. Подготовка окружения, сетевая безопасность и генерация секретов
AnythingLLM хранит свои учетные записи, настройки рабочих пространств, историю чатов и векторные базы внутри каталога /app/server/storage. Перед первым запуском необходимо подготовить структуру каталогов на сервере и создать файл конфигурации.
Создайте рабочую директорию проекта /opt/anythingllm с каталогом постоянного хранения данных storage:
sudo mkdir -p /opt/anythingllm/storage
cd /opt/anythingllm
🔒 Сетевая изоляция: порт 3001 не должен быть доступен из внешней сети
AnythingLLM слушает веб-интерфейс и API на порту 3001. Если пробросить этот порт наружу как 0.0.0.0:3001, Docker обойдет правила системного фаервола UFW через собственную цепочку NAT в iptables. Это откроет доступ к административному интерфейсу всему интернету без шифрования TLS. В производственном манифесте порт должен привязываться исключительно к локальному интерфейсу 127.0.0.1:3001, а внешний доступ должен контролировать Nginx с SSL-сертификатом.
Для подписи пользовательских сессий и токенов авторизации сгенерируйте стойкий криптографический ключ JWT_SECRET с помощью онлайн генератора паролей или стандартной утилиты openssl:
# Генерация надежного JWT-ключа (не менее 32 случайных символов)
openssl rand -base64 32
Создайте пустой файл переменных окружения внутри каталога хранения данных:
touch /opt/anythingllm/storage/.env
chmod 600 /opt/anythingllm/storage/.env
4. Манифест Docker Compose: запуск сервиса AnythingLLM v1.19
Мы зафиксируем образ на актуальном стабильном релизе mintplexlabs/anythingllm:v1.19.0. Обратите внимание на две ключевые переменные в конфигурации:
ENABLE_BUILT_IN_LLM=false(илиtrue) — флагманская возможность релиза v1.19.0. При значенииtrueAnythingLLM активирует встроенный движок инференса Lemonade (открытый сервер от AMD на базеllama.cpp). В этом случае отпадает необходимость разворачивать внешнюю Ollama — модели GGUF загружаются и исполняются прямо внутри контейнера. Если вы планируете использовать внешнюю Ollama или облачные API, оставьте значениеfalseдля экономии оперативной памяти.cap_add: [SYS_ADMIN]— системная привилегия ядра, требуемая для браузера Chromium (библиотека Puppeteer). Платформа использует Chromium для парсинга веб-страниц по URL и рендеринга сложных документов.
⚠️ Анализ безопасности: почему требуется SYS_ADMIN и как минимизировать риски
Привилегия SYS_ADMIN предоставляет контейнеру расширенный доступ к интерфейсам ядра Linux (в частности, к управлению пользовательскими пространствами имен user namespaces и вызовам clone/unshare), необходимым песочнице Chromium. В производственной среде обязательно изолируйте контейнер: ограничьте сетевой доступ директивой 127.0.0.1:3001, установите строгие лимиты памяти в блоке deploy.resources и монтируйте только выделенный каталог данных. Если парсинг внешних интернет-ссылок по URL в компании строго запрещен, а работа ведется только с локальными PDF-файлами, контейнер можно запускать без SYS_ADMIN, передав кастомный seccomp-профиль.
Создайте файл /opt/anythingllm/docker-compose.yml:
services:
anythingllm:
image: mintplexlabs/anythingllm:v1.19.0
container_name: anythingllm_app
restart: unless-stopped
ports:
# Веб-интерфейс и API доступны только локально на сервере
- "127.0.0.1:3001:3001"
cap_add:
# Необходимо для внутренней песочницы Chromium (парсинг веб-ссылок)
- SYS_ADMIN
environment:
# Путь к постоянному хранилищу внутри контейнера
- STORAGE_DIR=/app/server/storage
# Секретный ключ подписи сессий (замените на сгенерированный)
- JWT_SECRET=ВСТАВЬТЕ_СЮДА_КЛЮЧ_ОТ_OPENSSL_RAND_BASE64_32
# Отключение телеметрии для полной приватности
- DISABLE_TELEMETRY=true
# Встроенная векторная база данных LanceDB (на диске)
- VECTOR_DB=lancedb
# Новинка v1.19.0: встроенный инференс Lemonade/llama.cpp (true для автономной работы)
- ENABLE_BUILT_IN_LLM=false
volumes:
# Каталог с базой данных SQLite, документами и индексами LanceDB
- ./storage:/app/server/storage
- ./storage/.env:/app/server/.env
# Разрешаем контейнеру обращаться к сервисам на хосте (например, к внешней Ollama)
extra_hosts:
- "host.docker.internal:host-gateway"
# Стандартный синтаксис лимитов ресурсов Docker Compose v2 Specification
deploy:
resources:
limits:
cpus: "2.0"
memory: 2G
reservations:
memory: 512M
# Обратная совместимость с cgroups v1
mem_limit: 2g
cpus: 2.0
healthcheck:
test: ["CMD-SHELL", "curl -f http://127.0.0.1:3001/api/ping || exit 1"]
interval: 15s
timeout: 5s
retries: 3
start_period: 20s
networks:
default:
name: anythingllm_net
Параметр extra_hosts: ["host.docker.internal:host-gateway"] имеет решающее значение: он позволяет контейнеру AnythingLLM обращаться к локально запущенным на VDS службам (например, к Ollama на порту 11434 или к AI-шлюзу LiteLLM Proxy на порту 4000) по стабильному сетевому имени http://host.docker.internal:11434.
Запустите контейнер в фоновом режиме:
docker compose up -d
Убедитесь, что контейнер успешно запустился и прошел проверку работоспособности (Healthcheck):
docker compose ps
docker compose logs -f --tail=50
5. Первоначальная настройка: выбор языковой модели, эмбеддингов и LanceDB
При первом входе в систему платформа запускает мастер первоначальной конфигурации (Onboarding Wizard). На этом этапе задаются глобальные параметры для генерации ответов и векторизации.
1. Выбор LLM-провайдера (Language Model)
В разделе Settings → LLM Preference выберите удобный для вашей инфраструктуры источник генерации текста:
- Встроенный движок Built-in (Новинка v1.19.0 на базе Lemonade и llama.cpp). Если в
docker-compose.ymlустановлена переменнаяENABLE_BUILT_IN_LLM=true, выберите провайдер Built-in. Открытый движок Lemonade от AMD автоматически определяет инструкции процессора (AVX2/AVX-512) или серверную видеокарту (CUDA/ROCm/Vulkan) и позволяет скачивать рекомендованные модели (Llama 3.2, Qwen 2.5, Phi-3.5) или любые веса GGUF с Hugging Face прямо через веб-интерфейс. В этом сценарии вам вообще не потребуется устанавливать и настраивать сторонние сервисы инференса. - Локальная Ollama на VDS. Если у вас уже развернут системный демон Ollama, выберите
Ollamaи укажите в поле Ollama Base URL адресhttp://host.docker.internal:11434. В выпадающем списке отобразятся все модели, загруженные в демон (например,qwen2.5:7b-instructилиllama3.1:8b). Это обеспечивает 100% изоляцию данных внутри контура сервера. - Прямой API DeepSeek / OpenAI. Выберите
DeepSeekилиGeneric OpenAI, укажите эндпоинтhttps://api.deepseek.com/v1и ваш API-ключ. Модели DeepSeek-V3 и DeepSeek-R1 дают высочайшее качество рассуждений по регламентам на русском языке при стоимости в десятки раз ниже зарубежных аналогов. - LiteLLM Proxy. Если в компании развернут централизованный шлюз моделей, подключите AnythingLLM к эндпоинту
http://host.docker.internal:4000/v1для кэширования ответов в Redis и контроля бюджета отделов.
2. Настройка модели эмбеддингов (Embedder)
В разделе Settings → Embedding Preference настраивается преобразование текста в векторы:
- Встроенная модель AnythingLLM (Default). Работает прямо внутри контейнера без сторонних утилит (локальная модель
all-MiniLM-L6-v2). Оптимально для быстрого старта на компактных серверах. - Серверная модель Ollama. Если требуется максимальное качество сопоставления на русском языке, выберите Ollama и укажите модель
bge-m3илиnomic-embed-text. Модельbge-m3поддерживает мультиязычность и длину контекста до 8192 токенов.
3. Векторная база данных
В разделе Settings → Vector Database оставьте значение по умолчанию: LanceDB. База данных автоматически создаст необходимые файлы в директории /app/server/storage/lancedb и не требует администрирования.
6. Создание рабочих пространств (Workspaces) и загрузка документов
Главное преимущество AnythingLLM перед монолитными чат-ботами — концепция рабочих пространств (Workspaces). Каждое рабочее пространство имеет собственную изолированную векторную базу, независимый системный промпт и привязанные документы.
1. Организация пространств по отделам компании
Создайте отдельные пространства под задачи бизнеса:
legal-contracts— договоры, соглашения NDA, юридические регламенты (доступ открыт только юристам и руководству);hr-onboarding— инструкции для новых сотрудников, порядок отпусков, компенсаций и график работы;tech-ops— архитектурные схемы, регламенты дежурств, инструкции по бэкапам и настройке Nginx;sales-scripts— прайс-листы, сценарии звонков, матрицы возражений и описания продуктов.
2. Загрузка и индексация документов
Перейдите в нужное рабочее пространство, нажмите на иконку загрузки файлов (Upload Documents) и перетащите корпоративные файлы:
📁 hr-onboarding/
├── Регламент_отпусков_и_командировок_2026.pdf
├── Инструкция_по_охране_труда.docx
└── Структура_отделов_и_контакты.xlsx
После загрузки файла нажмите кнопку Move to Workspace, а затем — Save and Embed. Платформа запустит конвейер: извлечет текст, разобьет его на фрагменты (чанги), вычислит эмбеддинги и сохранит векторы в LanceDB. Статус файла изменится на Embedded.
3. Настройка режима диалога (Chat Modes)
Для каждого рабочего пространства доступно два ключевых режима работы:
- Query Mode (Строгий ответ по документам). Нейросеть отвечает строго на основе найденных фактов в загруженных файлах. Если информации в документах нет, модель прямо сообщает: «В предоставленных регламентах данная информация отсутствует». В конце каждого ответа выводятся кликабельные сноски с цитатами и номерами страниц первоисточника. Это исключает галлюцинации при работе с юридическими и финансовыми бумагами.
- Chat Mode (Общий диалог с контекстом). Модель использует документы компании как дополнительную базу знаний, но может давать общие пояснения, перефразировать текст и отвечать на сопутствующие вопросы.
Рекомендуемые VDS-провайдеры
Отказоустойчивые сервера с быстрыми NVMe и каналом до 1 Гбит/с
Timeweb Cloud — Производительные NVMe VDS
Скоростные серверы с быстрой дисковой подсистемой NVMe и высокой частотой процессора (до 3.3 ГГц) для моментального векторного поиска в LanceDB.
Selectel — Инфраструктура корпоративного уровня Tier III
Надежные серверы с защитой персональных данных по 152-ФЗ, гарантированными ресурсами и строгим SLA для закрытых корпоративных баз знаний.
Beget — Удобные VDS с установкой Docker в один клик
Интуитивная панель управления, предустановленный Docker на Ubuntu 24.04 LTS и круглосуточная русскоязычная техническая поддержка.
7. Настройка Nginx Reverse Proxy: SSL, WebSocket и SSE-стриминг ответов
Для организации безопасного доступа сотрудников через домен ai-docs.example.ru по протоколу HTTPS настроим веб-сервер Nginx.
В генеративных нейросетевых интерфейсах ответ формируется посимвольно (Server-Sent Events, SSE) или через WebSocket. Если Nginx будет буферизировать поток, пользователь не увидит плавного появления текста, а будет ждать 30–60 секунд до полной генерации ответа. Кроме того, загрузка больших PDF-документов и архивов требует снятия лимита на размер тела запроса.
Создайте конфигурационный файл /etc/nginx/sites-available/ai-docs.example.ru.conf:
server {
listen 80;
server_name ai-docs.example.ru;
# 1. Лимит на размер загружаемых корпоративных документов (PDF, архивы регламентов)
client_max_body_size 100M;
location / {
proxy_pass http://127.0.0.1:3001;
proxy_http_version 1.1;
# 2. Поддержка WebSocket для мгновенных уведомлений
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 3. Критически важно: отключение буферизации для плавного SSE-стриминга токенов
proxy_buffering off;
proxy_cache off;
chunked_transfer_encoding on;
# 4. Увеличенные таймауты для тяжелых рассуждений RAG
proxy_connect_timeout 300s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
}
}
Активируйте виртуальный хост и перезагрузите веб-сервер:
sudo ln -s /etc/nginx/sites-available/ai-docs.example.ru.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Выпустите бесплатный доверенный SSL-сертификат Let's Encrypt с автоматической переадресацией с HTTP на HTTPS:
sudo certbot --nginx -d ai-docs.example.ru --redirect --non-interactive --agree-tos -m admin@example.ru
Проверьте корректность SSL-цепочки через онлайн проверку SSL-сертификатов, а также убедитесь с помощью сканера открытых портов, что порт 3001 недоступен напрямую из интернета. Если вам требуется сгенерировать готовый конфиг под другие веб-серверы, воспользуйтесь нашим генератором Nginx Reverse Proxy онлайн.
8. Встраиваемый чат-виджет для внутреннего портала или сайта компании
AnythingLLM позволяет опубликовать отдельное рабочее пространство в виде плавающего веб-виджета. Это идеальный способ встроить интеллектуального помощника в корпоративную wiki-систему (Notion, Confluence, Docmost) или на сайт интернет-магазина для автоответов по прайс-листу и характеристикам товаров.
1. Активация виджета в рабочем пространстве
- Откройте настройки нужного рабочего пространства (например,
hr-onboarding). - Перейдите в раздел Chat Widget.
- Включите тумблер Enable Chat Widget.
- Задайте разрешенные домены (CORS Domain), например
https://portal.company.ru, чтобы исключить несанкционированное использование вашего API сторонними сайтами.
2. Размещение HTML-кода на страницах портала
Платформа сгенерирует готовый компактный сниппет JavaScript:
<!-- Подключение виджета AnythingLLM в подвал корпоративного портала -->
<script
data-embed-id="a8e4587a-321b-4f9e-a0e2-63bc1234abcd"
data-base-api-url="https://ai-docs.example.ru/api/embed"
src="https://ai-docs.example.ru/embed/anythingllm-chat-widget.min.js">
</script>
Виджет появляется в правом нижнем углу экрана: сотрудники могут задавать вопросы по регламентам без авторизации в основной административной панели AnythingLLM, а все диалоги изолированы в рамках назначенного рабочего пространства.
9. Резервное копирование базы знаний LanceDB, метаданных SQLite и обслуживание
Вся информация AnythingLLM — учетные записи пользователей, токены, настройки воркспейсов, загруженные файлы и векторные базы LanceDB — хранится в едином каталоге /opt/anythingllm/storage:
anythingllm.db— реляционная база данных SQLite (пользователи, история чатов, метаданные документов);lancedb/— файлы векторных индексов LanceDB по каждому рабочему пространству;documents/— оригиналы загруженных файлов, распарсенный JSON-текст и кэш чанков;.env— параметры окружения, криптографические ключи и токены провайдеров.
Для создания консистентного резервного архива базы знаний напишем bash-скрипт /opt/anythingllm/backup_anythingllm.sh:
#!/usr/bin/env bash
set -euo pipefail
BACKUP_DIR="/opt/anythingllm/backups"
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
mkdir -p "${BACKUP_DIR}"
# 1. Корректный горячий бэкап базы данных SQLite через встроенную команду .backup
sqlite3 /opt/anythingllm/storage/anythingllm.db ".backup '${BACKUP_DIR}/anythingllm_db_${TIMESTAMP}.sqlite'"
# 2. Архивирование векторных баз LanceDB, документов и файла конфигурации .env
tar -czf "${BACKUP_DIR}/anythingllm_full_${TIMESTAMP}.tar.gz" \
-C /opt/anythingllm \
storage/.env \
storage/lancedb \
storage/documents
# 3. Ротация: удаление локальных бэкапов старше 14 дней
find "${BACKUP_DIR}" -name "anythingllm_*" -type f -mtime +14 -delete
echo "[$(date)] Резервная копия AnythingLLM успешно создана: ${BACKUP_DIR}"
Сделайте скрипт исполняемым и добавьте его в системный планировщик crontab -e для ночного запуска:
chmod +x /opt/anythingllm/backup_anythingllm.sh
# 0 3 * * * /opt/anythingllm/backup_anythingllm.sh >> /var/log/anythingllm_backup.log 2>&1
💡 Отправка бэкапов в объектное хранилище S3
Для максимальной отказоустойчивости полученный архив рекомендуется сразу выгружать на независимый сервер бэкапов или в объектное хранилище через собственное хранилище Garage S3 или связку с утилитой Restic.
10. Чек-лист готовности AnythingLLM к корпоративной эксплуатации
| Элемент проверки | Рекомендуемый статус | Как верифицировать |
|---|---|---|
| Изоляция порта 3001 | 127.0.0.1:3001 | Команда ss -tulpn | grep 3001 показывает сокет только на 127.0.0.1. Внешний доступ закрыт фаерволом. |
| Сетевой шлюз extra_hosts | host.docker.internal | Контейнер успешно пингует и вызывает локальные сервисы хоста (Ollama / LiteLLM Proxy) по имени host.docker.internal. |
| Режим ответов без галлюцинаций | Query Mode | Для критических пространств (юристы, бухгалтерия) включен Query Mode со строгими ссылками на страницы регламентов. |
| SSE-стриминг в Nginx | proxy_buffering off | При генерации ответа текст в браузере появляется плавно в реальном времени без пауз на буферизацию. |
| Лимиты ресурсов cgroups | deploy.resources (2G RAM / 2 vCPU) | Команда docker stats anythingllm_app --no-stream подтверждает, что потребление ОЗУ укладывается в рамки лимитов Compose. |
| Горячий бэкап LanceDB и SQLite | Настроен в cron | Архивы anythingllm_full_*.tar.gz создаются ежесуточно и успешно открываются через tar -tzf. |