Self-Hosted AI Stack

September 14, 2026 · View on GitHub

English | 简体中文 | 繁體中文 | Русский

Self-Hosted AI Stack

Powered by Docker Compose  Docker Pulls  Лицензия: MIT

Self-Hosted AI Stack: разверните полный self-hosted AI-стек одной командой

Включает Ollama, LiteLLM, AnythingLLM, Whisper, MCP Gateway, Embeddings, Docling и Kokoro — полностью сконфигурирован и готов к запуску с Docker Compose.

📘 Kindle Countdown Deal: $0.99/£0.99 (только в США и Великобритании). The Self-Hosted AI Builder’s Guide — практическое руководство по развертыванию, защите и эксплуатации этого приватного AI-стека.

Возможности:

  • Без настройки: все сервисы автоматически конфигурируются при первом запуске
  • Безопасность по умолчанию: защита AnythingLLM паролем включена, а встроенные API-сервисы автоматически генерируют ключи
  • Готовность к HTTPS: опциональный Caddy overlay предоставляет автоматический TLS и привязывает прямые HTTP-порты к localhost
  • Приватность: по умолчанию работает локально с опциональной поддержкой внешних провайдеров через LiteLLM
  • Гибкость: модели, порты, провайдеры и API-ключи настраиваются через простые env-файлы
  • Облегчённые стеки с меньшими требованиями к памяти (от ~4.5 ГБ)
  • GPU-ускорение через NVIDIA CUDA
  • Мультиархитектурность: linux/amd64, linux/arm64

Включённые сервисы

СервисНазначениеПорт по умолчанию
Ollama (LLM)Запуск локальных LLM-моделей (llama3, qwen, mistral и др.)11434
AnythingLLMВеб-чат — защита паролем включена по умолчанию3001
LiteLLMAI-шлюз — маршрутизация запросов к Ollama, OpenAI, Anthropic и 100+ провайдерам4000
EmbeddingsПреобразование текста в векторы для семантического поиска и RAG8000
Whisper (STT)Транскрибация речи в текст9000
WhisperLive (STT в реальном времени)Транскрибация речи в реальном времени через WebSocket9090
Kokoro (TTS)Преобразование текста в естественную речь8880
MCP GatewayПредоставление MCP-инструментов (файловая система, веб, GitHub, поиск, базы данных) AI-клиентам3000
DoclingКонвертирует документы (PDF, DOCX и др.) в структурированный текст/Markdown5001

Быстрый старт

Требования:

  • Linux-сервер (локальный или облачный) с установленным Docker
  • Минимум 8 ГБ оперативной памяти (с небольшими моделями). Для крупных LLM-моделей (8B+) рекомендуется 16 ГБ и более.
  • Вы можете закомментировать ненужные сервисы для уменьшения потребления памяти.

Запуск полного стека:

# Клонируйте репозиторий для получения compose-файлов
git clone https://github.com/hwdsl2/self-hosted-ai-stack
cd self-hosted-ai-stack
docker compose up -d

Существующие установки: Если вы клонировали проект до переименования из docker-ai-stack, существующий checkout и развёртывание продолжают работать. GitHub перенаправляет старый URL репозитория, и вам не нужно переименовывать локальный каталог, контейнеры, тома или сети.

Учётные данные PostgreSQL: Новые установки и существующие установки с паролем по умолчанию обрабатываются автоматически. Если вы ранее задали собственный пароль базы данных, см. Учётные данные PostgreSQL перед запуском.

Загрузка модели (обязательно перед отправкой LLM-запросов):

docker exec ollama ollama_manage --pull llama3.2:3b

Запустите проверку работоспособности, чтобы убедиться, что все сервисы работают:

./stack-check.sh

Совет: При первом запуске сервисам может потребоваться несколько минут для инициализации. Если какие-либо проверки не пройдены, подождите и запустите ./stack-check.sh снова. Используйте docker compose logs для проверки прогресса.

Подробную диагностику см. в руководстве Устранение неполадок.

Получение мастер-ключа LiteLLM (используется для входа в панель администратора и LLM-запросов):

docker exec litellm litellm_manage --showkey
Показать основные API-ключи (Ollama, LiteLLM, MCP Gateway)
docker exec ollama ollama_manage --showkey
docker exec litellm litellm_manage --showkey
docker exec mcp mcp_manage --showkey

Доступ к AnythingLLM (чат-интерфейс):

AnythingLLM предварительно настроен для подключения к локальной языковой модели через LiteLLM. При первом запуске может потребоваться несколько минут для готовности (проверяйте прогресс командой docker logs anythingllm).

Защита паролем по умолчанию. При первом запуске автоматически генерируется случайный пароль администратора, выводится один раз в docker logs anythingllm и сохраняется в /app/server/storage/.initial_admin_password внутри тома anythingllm-data. Сгенерированный пароль сохраняется при обновлении контейнера. Изменить его можно в любой момент через Settings → Security; после изменения .initial_admin_password может больше не совпадать с текущим паролем входа.

Получить автоматически сгенерированный пароль:

# В любой момент из тома данных:
docker exec anythingllm cat /app/server/storage/.initial_admin_password

# Или из живых логов (показывается только при первом запуске):
docker compose logs anythingllm | grep -A4 "FIRST RUN"

Откройте http://<server-ip>:3001 в браузере и войдите с указанным выше паролем.

Совет: При предоставлении доступа к AnythingLLM за пределами localhost или доверенной локальной сети используйте включённый Caddy HTTPS overlay, чтобы пароль шифровался при передаче, а прямые HTTP-порты были привязаны к localhost. См. ниже Развёртывание с доступом из интернета.

Доступ к панели администратора LiteLLM:

Откройте http://<server-ip>:4000/ui в браузере. Войдите с именем пользователя admin и вашим мастер-ключом LiteLLM в качестве пароля. Панель администратора предоставляет управление виртуальными ключами, отслеживание расходов и настройку моделей.

Совет: В панели администратора нажмите Playground в левом меню. Выберите локальную модель (например, ollama-chat/llama3.2:3b) из выпадающего списка и начните общаться — это быстрый способ убедиться, что локальная языковая модель работает сквозным образом.

Остановка стека:

# Остановка и удаление всех контейнеров (данные сохраняются в Docker-томах)
docker compose down

Сообщество

Self-Hosted AI Stack поддерживается автором Setup IPsec VPN (28k+ звёзд).

GPU-ускорение (NVIDIA CUDA)

Для GPU-ускорения NVIDIA используйте CUDA compose-файл:

docker compose -f docker-compose.cuda.yml up -d

Совет: Чтобы не добавлять -f docker-compose.cuda.yml к каждой последующей команде docker compose (down, pull, logs и т. д.), задайте её один раз для текущей сессии shell:

export COMPOSE_FILE=docker-compose.cuda.yml

Затем выполняйте обычные команды docker compose как всегда. Чтобы сделать это постоянным, добавьте COMPOSE_FILE=docker-compose.cuda.yml в файл .env в этом каталоге. Выполните unset COMPOSE_FILE, чтобы вернуться к конфигурации CPU.

Требования: GPU NVIDIA, драйвер NVIDIA 575.57.08+ (Linux) или 576.57+ (Windows), и NVIDIA Container Toolkit, установленный на хосте. CUDA-образы поддерживают только linux/amd64.

Пользователям Podman: Podman игнорирует блок GPU deploy: в Compose. Используйте вместо него CDI — см. Использование Podman.

Облегчённые стеки

Не нужен полный стек? Используйте преднастроенное подмножество из папки stacks/:

Примечание: Лёгкие подстеки используют общие стандартные имена контейнеров, порты и имена Docker volumes. С compose-файлами по умолчанию запускайте только один вариант подстека за раз; перед переключением на другой вариант остановите текущий. Чтобы объединить возможности, используйте полный стек или настройте имена проектов Compose, имена контейнеров, порты и тома.

СтекСервисыПамятьСценарий использования
chat-uiOllama + LiteLLM + AnythingLLM~5 ГБВеб-интерфейс для чата в стиле ChatGPT
voice-pipelineWhisper + Ollama + LiteLLM + Kokoro~6 ГБРечь в текст → LLM → текст в речь
voice-chatWhisper + Ollama + LiteLLM + Kokoro + AnythingLLM~6.5 ГБЧат-интерфейс с голосовым вводом/выводом
rag-pipelineOllama + LiteLLM + Embeddings~5 ГБСемантический поиск + LLM Q&A
rag-pipeline-fullOllama + LiteLLM + Embeddings + Docling~6 ГБРазбор документов + семантический поиск + LLM Q&A
code-assistantOllama + LiteLLM + MCP Gateway + Embeddings~5 ГБAI-разработка с инструментами + семантический поиск по коду
ai-toolsOllama + LiteLLM + MCP Gateway~5 ГБAI-ассистент для разработки с доступом к инструментам
chat-onlyOllama + LiteLLM~4.5 ГБМинимальная локальная замена ChatGPT
git clone https://github.com/hwdsl2/self-hosted-ai-stack
cd self-hosted-ai-stack/stacks/chat-ui  # или voice-pipeline, voice-chat, rag-pipeline, rag-pipeline-full, code-assistant, ai-tools, chat-only
docker compose up -d

Архитектура

graph LR
    A["🎤 Аудиовход"] -->|транскрибация| W["Whisper<br/>(речь в текст)"]
    D["📄 Документы"] -->|разбор| DC["Docling<br/>(документ → текст)"]
    DC -->|эмбеддинг| E["Embeddings<br/>(текст → векторы)"]
    E -->|хранение| VDB["pgvector<br/>(в общем Postgres)"]
    W -->|запрос| E
    VDB -->|контекст| L["LiteLLM<br/>(AI-шлюз)"]
    W -->|текст| L
    L -->|маршрутизация| O["Ollama<br/>(локальная LLM)"]
    L -->|ответ| T["Kokoro TTS<br/>(текст в речь)"]
    T --> B["🔊 Аудиовыход"]
    C["🤖 AI-клиент<br/>(Cline, Claude и др.)"] -->|MCP-инструменты| M["MCP Gateway<br/>(MCP-эндпоинт)"]
    C -->|чат| L
    L -->|MCP-протокол| M
    U["👤 Пользователь"] -->|чат| AN["AnythingLLM<br/>(чат-интерфейс)"]
    AN -->|запросы к LLM| L
    AN -->|MCP-инструменты| M
    U -->|использует| C
    U -->|говорит| A
    U -->|загружает| D

Примечания:

  • Порт Ollama (11434) и порт MCP Gateway (3000) доступны только внутри сети Docker и не открыты на хосте по умолчанию. Доступ к LLM осуществляется через LiteLLM на порту 4000.
  • Для снижения потребления памяти сервисы Kokoro (TTS), Docling (парсинг документов) и WhisperLive (распознавание речи в реальном времени) по умолчанию отключены. Чтобы включить их, раскомментируйте соответствующие сервисы в docker-compose.yml.

Запуск без Docker Compose

Если вы предпочитаете использовать команды docker run напрямую, сначала создайте общую сеть для связи между сервисами:

docker network create ai-stack

Затем сгенерируйте пароль PostgreSQL и запустите каждый сервис в общей сети:

Примечание: При ручном использовании docker run дождитесь готовности каждой зависимости перед запуском сервисов, которые её используют (например, дождитесь PostgreSQL и других зависимостей, например Ollama или MCP, перед запуском LiteLLM; если используется AnythingLLM, дождитесь готовности LiteLLM перед его запуском). В примерах ниже создаётся одна переменная пароля PostgreSQL и повторно используется для Postgres и LiteLLM.

LITELLM_POSTGRES_PASSWORD=$(LC_ALL=C tr -dc 'A-Za-z0-9' </dev/urandom | head -c 32)

# PostgreSQL with pgvector (required by LiteLLM; pgvector enables vector storage for RAG)
docker run -d --name litellm-db --restart always \
    --network ai-stack \
    -e POSTGRES_USER=litellm \
    -e POSTGRES_PASSWORD="$LITELLM_POSTGRES_PASSWORD" \
    -e POSTGRES_DB=litellm \
    -v litellm-db:/var/lib/postgresql \
    pgvector/pgvector:pg18-trixie

# Ollama (LLM)
docker run -d --name ollama --restart always \
    --network ai-stack \
    -v ollama-data:/var/lib/ollama \
    -v ollama-shared:/var/lib/ollama-shared \
    hwdsl2/ollama-server

# MCP Gateway
docker run -d --name mcp --restart always \
    --network ai-stack \
    -v mcp-data:/var/lib/mcp \
    -v mcp-shared:/var/lib/mcp-shared \
    hwdsl2/mcp-gateway

# LiteLLM (AI-шлюз)
docker run -d --name litellm --restart always \
    --network ai-stack \
    -p 4000:4000 \
    -e LITELLM_OLLAMA_BASE_URL=http://ollama:11434 \
    -e LITELLM_MCP_URL=http://mcp:3000/mcp \
    -e LITELLM_DATABASE_URL="postgresql://litellm:${LITELLM_POSTGRES_PASSWORD}@litellm-db:5432/litellm" \
    -v litellm-data:/etc/litellm \
    -v ollama-shared:/var/lib/ollama-shared:ro \
    -v mcp-shared:/var/lib/mcp-shared:ro \
    -v litellm-shared:/var/lib/litellm-shared \
    hwdsl2/litellm-server

# Embeddings
docker run -d --name embeddings --restart always \
    --network ai-stack \
    -p 127.0.0.1:8000:8000 \
    -v embeddings-data:/var/lib/embeddings \
    hwdsl2/embeddings-server

# Whisper (STT)
docker run -d --name whisper --restart always \
    --network ai-stack \
    -p 127.0.0.1:9000:9000 \
    -v whisper-data:/var/lib/whisper \
    hwdsl2/whisper-server

# WhisperLive (real-time STT)
docker run -d --name whisper-live --restart always \
    --network ai-stack \
    -p 127.0.0.1:9090:9090 \
    -v whisper-live-data:/var/lib/whisper-live \
    hwdsl2/whisper-live-server

# AnythingLLM (чат-интерфейс)
docker run -d --name anythingllm --restart always \
    --network ai-stack \
    -p 3001:3001 \
    -e STORAGE_DIR=/app/server/storage \
    -e LLM_PROVIDER=generic-openai \
    -e GENERIC_OPEN_AI_BASE_PATH=http://litellm:4000/v1 \
    -e GENERIC_OPEN_AI_MODEL_PREF=ollama/llama3.2:3b \
    -e GENERIC_OPEN_AI_MODEL_TOKEN_LIMIT=131072 \
    -e ANYTHINGLLM_DEFAULT_CHAT_MODE=chat \
    -e EMBEDDING_ENGINE=native \
    -e DISABLE_TELEMETRY=true \
    -v anythingllm-data:/app/server/storage \
    -v litellm-shared:/var/lib/litellm-shared:ro \
    -v "$(pwd)/chat-ui-bootstrap.sh:/usr/local/bin/chat-ui-bootstrap.sh:ro" \
    --entrypoint /bin/bash \
    mintplexlabs/anythingllm:1.16.1 \
    /usr/local/bin/chat-ui-bootstrap.sh

# Kokoro (TTS)
docker run -d --name kokoro --restart always \
    --network ai-stack \
    -p 127.0.0.1:8880:8880 \
    -v kokoro-data:/var/lib/kokoro \
    hwdsl2/kokoro-server

# Docling (разбор документов)
docker run -d --name docling --restart always \
    --network ai-stack \
    -p 127.0.0.1:5001:5001 \
    -v docling-data:/var/lib/docling \
    hwdsl2/docling-server

Примечание: Общая сеть позволяет сервисам обращаться друг к другу по имени контейнера (например, LiteLLM подключается к Ollama через http://ollama:11434). Вы можете запускать только нужные сервисы — не обязательно запускать все.

Загрузка модели (обязательно перед отправкой LLM-запросов):

docker exec ollama ollama_manage --pull llama3.2:3b

Использование Podman

Стек работает под Podman на основе наилучших усилий. Compose-файлы для CPU работают без изменений; для GPU-ускорения и хостов с включённым SELinux нужны несколько дополнительных шагов, описанных ниже. Рекомендуется Podman 4.1+.

1. Установите слой совместимости с Docker CLI. Чтобы команды docker из этого README и скрипт проверки stack-check.sh работали без изменений, установите пакет podman-docker (предоставляет обёртку dockerpodman):

# Fedora / RHEL / CentOS Stream
sudo dnf install -y podman-docker

# Debian / Ubuntu
sudo apt-get install -y podman-docker

Примечание: Псевдонима оболочки alias docker=podman недостаточно — псевдонимы не видны скриптам, таким как stack-check.sh. Используйте пакет podman-docker (или символическую ссылку dockerpodman в PATH). Кроме того, stack-check.sh автоматически определяет Podman; вы также можете явно указать его через CONTAINER_ENGINE=podman ./stack-check.sh.

2. Установите провайдер Compose. podman compose делегирует выполнение внешнему провайдеру. Установите podman-compose или docker-compose:

# Fedora / RHEL / CentOS Stream
sudo dnf install -y podman-compose

# Debian / Ubuntu
sudo apt-get install -y podman-compose

3. Запустите стек. При установленном слое совместимости каждая команда из этого README работает без изменений. Без него замените docker на podman:

git clone https://github.com/hwdsl2/self-hosted-ai-stack
cd self-hosted-ai-stack
podman compose up -d

Запустите проверку работоспособности (движок определяется автоматически):

./stack-check.sh

GPU-ускорение (CDI). Podman не читает блок GPU deploy.resources в Compose. Вместо этого используйте Container Device Interface (CDI). После установки NVIDIA Container Toolkit сгенерируйте спецификацию CDI:

sudo nvidia-ctk cdi generate --output=/etc/cdi/nvidia.yaml

Затем предоставьте GPU соответствующим сервисам. Для podman compose замените блок deploy: у сервисов ollamawhisper) в docker-compose.cuda.yml на запись devices::

    devices:
      - nvidia.com/gpu=all

Для обычной команды podman run добавьте --device nvidia.com/gpu=all.

SELinux. На хостах с включённым SELinux (Fedora, RHEL, CentOS Stream) для смонтированных файлов нужен суффикс переразметки, иначе контейнеру будет отказано в доступе. Добавьте :z (общий) к монтированию chat-ui-bootstrap.sh:

  • В docker-compose.yml: измените ./chat-ui-bootstrap.sh:/usr/local/bin/chat-ui-bootstrap.sh:ro на ./chat-ui-bootstrap.sh:/usr/local/bin/chat-ui-bootstrap.sh:ro,z
  • В команде podman run выше: измените "$(pwd)/chat-ui-bootstrap.sh:/usr/local/bin/chat-ui-bootstrap.sh:ro" на "$(pwd)/chat-ui-bootstrap.sh:/usr/local/bin/chat-ui-bootstrap.sh:ro,z"

Именованным томам переразметка не требуется.

Дальнейшие шаги: Загрузите модель и подключитесь к сервисам — следуйте инструкциям в разделе Быстрый старт, начиная с «Загрузка модели». При установленном пакете podman-docker все команды работают без изменений.

Подключение MCP Gateway к LiteLLM

В compose-файлах этого репозитория LiteLLM и MCP Gateway подключаются автоматически — ручная настройка ключей не требуется.

API-ключи автоматически передаются между сервисами через общие Docker-тома:

  • Ollama генерирует API-ключ при первом запуске и копирует его в общий том
  • MCP Gateway делает то же самое
  • LiteLLM считывает оба ключа из общих томов при запуске

Переменные LITELLM_MCP_URL=http://mcp:3000/mcp и LITELLM_OLLAMA_BASE_URL=http://ollama:11434 уже заданы в compose-файлах, поэтому все сервисы подключаются автоматически одной командой docker compose up -d.

После подключения AI-клиенты, обращающиеся к LiteLLM, смогут использовать MCP-инструменты (файловая система, web-fetch, GitHub и др.) напрямую через прокси LiteLLM.

Пример голосового конвейера

Транскрибируйте голосовой вопрос, получите ответ от локальной LLM через Ollama и преобразуйте его в речь:

Примечание: Kokoro (TTS) отключён по умолчанию. Чтобы использовать этот пример, сначала раскомментируйте сервис kokoro в файле docker-compose.yml, затем выполните docker compose up -d.

Совет: Нужен образец аудиофайла? Скачайте этот образец английской речи (WAV, лицензия MIT) из репозитория Azure Samples:

curl -L -o sample_speech.wav \
    "https://github.com/Azure-Samples/cognitive-services-speech-sdk/raw/master/sampledata/audiofiles/katiesteve.wav"
LITELLM_KEY=$(docker exec litellm litellm_manage --getkey)
WHISPER_KEY=$(docker exec whisper whisper_manage --getkey)
KOKORO_KEY=$(docker exec kokoro kokoro_manage --getkey)

# Шаг 1: Транскрибация аудио в текст (Whisper)
TEXT=$(curl -s http://localhost:9000/v1/audio/transcriptions \
    -H "Authorization: Bearer $WHISPER_KEY" \
    -F file=@sample_speech.wav -F model=whisper-1 | jq -r .text)

# Шаг 2: Отправка текста в Ollama через LiteLLM и получение ответа
RESPONSE=$(curl -s http://localhost:4000/v1/chat/completions \
    -H "Authorization: Bearer $LITELLM_KEY" \
    -H "Content-Type: application/json" \
    -d "{\"model\":\"ollama/llama3.2:3b\",\"messages\":[{\"role\":\"user\",\"content\":\"$TEXT\"}]}" \
    | jq -r '.choices[0].message.content')

# Шаг 3: Преобразование ответа в речь (Kokoro TTS)
curl -s http://localhost:8880/v1/audio/speech \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $KOKORO_KEY" \
    -d "{\"model\":\"tts-1\",\"input\":\"$RESPONSE\",\"voice\":\"af_heart\"}" \
    --output response.mp3

Векторная база данных

PostgreSQL в этом стеке поставляется с расширением pgvector, поэтому вы можете хранить и запрашивать эмбеддинги в той же базе данных, которую использует LiteLLM — отдельная векторная база данных не требуется.

Включите расширение один раз (база данных сохраняется, поэтому это нужно сделать только однажды):

docker exec litellm-db psql -U litellm -d litellm -c 'CREATE EXTENSION IF NOT EXISTS vector;'

Проверьте, что оно включено:

docker exec litellm-db psql -U litellm -d litellm -c "SELECT extname, extversion FROM pg_extension WHERE extname='vector';"

Затем можно создать таблицу со столбцом vector (используйте размерность вашей модели эмбеддингов — например, 384 для модели по умолчанию BAAI/bge-small-en-v1.5) и выполнять поиск по сходству с помощью оператора <=>. Для большего масштаба или гибридного поиска можно использовать отдельную векторную базу данных, например Qdrant или Chroma.

Пример RAG-конвейера

Создание эмбеддингов документов для семантического поиска, извлечение контекста и ответы на вопросы с помощью локальной модели Ollama:

LITELLM_KEY=$(docker exec litellm litellm_manage --getkey)
EMBED_KEY=$(docker exec embeddings embed_manage --getkey)

# Шаг 1: Создание эмбеддинга фрагмента документа и сохранение вектора в векторной БД
curl -s http://localhost:8000/v1/embeddings \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $EMBED_KEY" \
    -d '{"input": "Docker simplifies deployment by packaging apps in containers.", "model": "text-embedding-ada-002"}' \
    | jq '.data[0].embedding'
# → Сохраните возвращённый вектор вместе с исходным текстом в pgvector (входит в Postgres этого стека) или в другую векторную БД, например Qdrant или Chroma.

# Шаг 2: При запросе создайте эмбеддинг вопроса, извлеките наиболее релевантные фрагменты
#          из векторной БД, затем отправьте вопрос и контекст в Ollama через LiteLLM.
curl -s http://localhost:4000/v1/chat/completions \
    -H "Authorization: Bearer $LITELLM_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "ollama/llama3.2:3b",
      "messages": [
        {"role": "system", "content": "Answer using only the provided context."},
        {"role": "user", "content": "What does Docker do?\n\nContext: Docker simplifies deployment by packaging apps in containers."}
      ]
    }' \
    | jq -r '.choices[0].message.content'

Пример MCP-инструментов

Используйте MCP Gateway для предоставления AI-ассистенту доступа к файлам, вебу и GitHub:

По умолчанию MCP Gateway доступен только внутри Docker-сети. Перед использованием http://localhost:3000/mcp из AI-клиента на хосте или через curl на хосте раскомментируйте проброс порта 3000:3000/tcp для сервиса mcp в docker-compose.yml и перезапустите сервис.

MCP_KEY=$(docker exec mcp mcp_manage --getkey)

# Используйте MCP-эндпоинт с AI-клиентом (например, Cline в VS Code)
# URL MCP-сервера: http://localhost:3000/mcp
# Заголовок Authorization: Bearer <api_key>

# Или протестируйте MCP-эндпоинт напрямую
curl -s http://localhost:3000/mcp \
    -X POST \
    -H "Authorization: Bearer $MCP_KEY" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json, text/event-stream" \
    -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'

Счётчики использования

Self-Hosted AI Stack использует анонимные агрегированные счётчики загрузок GitHub release assets, чтобы понимать использование и расставлять приоритеты для будущих улучшений. Он не отправляет telemetry payload и не использует приватный сборщик.

Чтобы отключить счётчики использования при запуске стека:

AI_STACK_DISABLE_USAGE_COUNTS=1 docker compose up -d

Настройка

Каждый сервис можно настроить с помощью опционального env-файла. Скопируйте пример env-файла из соответствующего репозитория, отредактируйте его и раскомментируйте монтирование тома в docker-compose.yml:

СервисEnv-файлРепозиторий
Ollamaollama.envdocker-ollama
LiteLLMlitellm.envdocker-litellm
Embeddingsembed.envdocker-embeddings
Whisperwhisper.envdocker-whisper
WhisperLivewhisper-live.envdocker-whisper-live
Kokorokokoro.envdocker-kokoro
MCP Gatewaymcp.envdocker-mcp-gateway
Doclingdocling.envdocker-docling

AnythingLLM настраивается через веб-интерфейс по адресу http://<IP-сервера>:3001. Вы можете изменить провайдера LLM, модель, движок эмбеддингов и другие параметры в разделе Settings. Подробнее см. документацию AnythingLLM.

Использование сервиса Embeddings из стека (опционально). По умолчанию AnythingLLM выполняет эмбеддинги внутри своего процесса с помощью встроенной модели MiniLM и сохраняет векторы в собственной LanceDB. Чтобы вместо этого использовать сервис Embeddings из стека (BAAI/bge-small-en-v1.5) и/или Postgres с включённым pgvector, отредактируйте сервис anythingllm в docker-compose.yml: закомментируйте EMBEDDING_ENGINE=native и раскомментируйте опциональный блок под ним. Также раскомментируйте примечание depends_on, чтобы сервисы embeddings/db запускались первыми. Когда включён VECTOR_DB=pgvector и PGVECTOR_CONNECTION_STRING не задан, AnythingLLM автоматически использует сгенерированный пароль Postgres из ai-stack-shared. AnythingLLM автоматически создаёт расширение vector и таблицу anythingllm_vectors при первом использовании. ⚠️ Переключение движка эмбеддингов или векторного хранилища на существующем развёртывании делает ранее проиндексированные документы несовместимыми — повторно проиндексируйте свои рабочие пространства после смены.

Подробные параметры настройки, справочник API и управление моделями описаны в документации каждого сервиса.

Развёртывание с доступом из интернета

По умолчанию все сервисы слушают по незашифрованному HTTP. Для развёртываний с доступом из интернета можно использовать включённый Caddy overlay для автоматического HTTPS. В режиме прокси Caddy является единственным публичным слушателем на портах 80 и 443; прямые порты AnythingLLM и LiteLLM заново привязываются к 127.0.0.1.

Требования:

  • Docker Compose 2.24.4+ (требуется для переопределения портов в proxy overlay)
  • DNS-запись A/AAAA для вашего домена указывает на этот сервер
  • В firewall/security group открыты входящие 80/tcp, 443/tcp и желательно 443/udp
  • На хосте нет другого сервиса, уже использующего порты 80 или 443

CPU-стек:

DOMAIN=chat.example.com ACME_EMAIL=you@example.com \
  docker compose -f docker-compose.yml -f docker-compose.proxy.yml up -d

CUDA-стек:

DOMAIN=chat.example.com ACME_EMAIL=you@example.com \
  docker compose -f docker-compose.cuda.yml -f docker-compose.proxy.yml up -d

Откройте https://chat.example.com (замените на ваш DOMAIN) для доступа к AnythingLLM. В режиме прокси http://127.0.0.1:3001 и http://127.0.0.1:4000/ui остаются доступны на самом хосте, но прямые порты 3001 и 4000 недоступны извне сервера.

Стандартные compose-файлы публикуют LiteLLM на порту 4000. Proxy overlay меняет этот прямой порт на доступный только через localhost, а включённый Caddyfile по умолчанию маршрутизирует только AnythingLLM. Если раскомментировать опциональный блок с отдельным hostname для LiteLLM, LiteLLM будет открыт через Caddy, поэтому храните мастер-ключ LiteLLM в секрете.

Диагностика:

docker logs ai-stack-caddy
# Используйте те же файлы -f, с которыми запускали стек
docker compose -f docker-compose.yml -f docker-compose.proxy.yml ps

Если Caddy сообщает о неизвестной директиве request_body, загрузите текущий образ caddy:2 и перезапустите overlay.

Пользователи старых версий Docker Compose или Podman по-прежнему могут использовать обратный прокси на хосте: привяжите прямые HTTP-порты к localhost (например, "127.0.0.1:3001:3001/tcp" и "127.0.0.1:4000:4000/tcp") и проксируйте на эти localhost-порты. Примеры Caddy и nginx для этого стека см. в разделе ручного обратного прокси Chat UI.

При открытии сервисов в интернет используйте сгенерированные API-ключи, если они есть. Для существующих развёртываний без ключей сначала задайте API-ключи через соответствующие env-файлы.

Резервное копирование и восстановление

Ваши API-ключи, модели и конфигурация хранятся в Docker-томах. Создайте резервную копию перед обновлением или внесением изменений:

# Экспорт API-ключей (при работающих контейнерах)
docker exec ollama ollama_manage --getkey
docker exec litellm litellm_manage --getkey
docker exec mcp mcp_manage --getkey
# Опциональные сервисы; игнорируются, если контейнер не включён или не запущен
docker exec whisper whisper_manage --getkey 2>/dev/null || true
docker exec whisper-live whisper_live_manage --getkey 2>/dev/null || true
docker exec kokoro kokoro_manage --getkey 2>/dev/null || true
docker exec embeddings embed_manage --getkey 2>/dev/null || true
docker exec docling docling_manage --getkey 2>/dev/null || true

# Резервное копирование всех томов (сначала остановите сервисы)
# Остановка и удаление всех контейнеров (данные сохраняются в Docker-томах)
docker compose down
mkdir -p backups
for vol in ollama-data litellm-data litellm-db ai-stack-shared embeddings-data whisper-data whisper-live-data kokoro-data mcp-data docling-data anythingllm-data caddy-data caddy-config; do
  docker volume inspect "$vol" >/dev/null 2>&1 && \
    docker run --rm -v "${vol}:/source:ro" -v "$(pwd)/backups:/backup" \
      alpine tar czf "/backup/${vol}.tar.gz" -C /source .
done

Примечание: Резервируйте ai-stack-shared вместе с litellm-db; новые установки хранят там сгенерированный пароль PostgreSQL. Тома ollama-shared, mcp-shared и litellm-shared являются временными томами для передачи ключей и не требуют резервного копирования.

Инструкции по восстановлению, миграции на новый сервер и полный контрольный список перед обновлением см. в руководстве Резервное копирование и восстановление.

Учётные данные PostgreSQL

Новые установки Docker Compose автоматически генерируют случайный пароль PostgreSQL и сохраняют его в томе ai-stack-shared. Существующие установки с паролем по умолчанию продолжают использовать старый пароль базы данных litellm для совместимости.

Если вы ранее настроили собственный пароль базы данных, задайте LITELLM_POSTGRES_PASSWORD в окружении shell с текущим паролем перед запуском docker compose up -d или сохраните явное переопределение LITELLM_DATABASE_URL в litellm.env.

Обновление образов

Обновление всех сервисов до последних версий:

git pull
docker compose pull
docker compose up -d
./stack-check.sh

После перезапуска стека выполните ./stack-check.sh, чтобы проверить сервисы и настройку сгенерированных учётных данных.

git pull обновляет все файлы проекта (включая изменения compose-файлов); docker compose pull обновляет образы сервисов. Если вы изменяли docker-compose.yml, git pull объединит изменения автоматически или попросит разрешить конфликт, если изменены одни и те же строки.

Одноразовое примечание для старых установок: Если вы задали пароль AnythingLLM до исправления сохранения .env, первое пересоздание контейнера после обновления может очистить этот пароль и оставить AnythingLLM без защиты. После обновления сразу откройте AnythingLLM и проверьте, что защита паролем по-прежнему включена. Если нет, задайте новый пароль в Settings → Security. При следующих пересозданиях контейнера пароль будет сохраняться.

AnythingLLM закреплен на стабильном теге релиза, а не на latest, потому что upstream-образ latest отслеживает ветку master. Когда выйдет новый релиз AnythingLLM, сначала создайте резервную копию, обновите тег в compose-файлах, затем выполните команды выше.

Ваши данные сохраняются в Docker-томах. Всегда создавайте резервную копию перед обновлением.

Лицензия

Copyright (C) 2026 Lin Song
Данный проект лицензирован на условиях лицензии MIT.

Данный проект представляет собой независимую Docker-конфигурацию и не аффилирован с Docker, Inc., Ollama, Berri AI (LiteLLM), Hugging Face, hexgrad (Kokoro), OpenAI, SYSTRAN или MCPHub, не одобрен и не спонсирован ими. Docker является товарным знаком или зарегистрированным товарным знаком Docker, Inc.