ЗАЧЕМ ЭТО НУЖНО
Три причины, по которым команды поднимают своё вместо подписки:
- Приватность. Код, договоры и переписка не уходят в чужое облако. Для многих отраслей это не пожелание, а требование.
- Стоимость. Подписка на команду из 20 человек за год стоит как приличная видеокарта, которая потом работает бесконечно.
- Доступность. Нет зависимости от блокировок, валютных карт и внезапных смен тарифа.
ЧТО ПОНАДОБИТСЯ
| Компонент | Минимум | Комфортно |
|---|---|---|
| GPU | RTX 3060 12GB | RTX 4090 / A6000 |
| RAM | 16 ГБ | 64 ГБ |
| Диск | 100 ГБ SSD | 1 ТБ NVMe |
| ОС | Ubuntu 22.04+ | Ubuntu 24.04 LTS |
Без GPU тоже заработает, но на CPU генерация идёт 1-2 токена в секунду — для демонстрации сойдёт, для работы нет.
ШАГ 1: DOCKER COMPOSE
Один файл поднимает весь стек. Кладём в /opt/ai-server/docker-compose.yml:
services:
ollama:
image: ollama/ollama:latest
container_name: ollama
restart: unless-stopped
volumes:
- ./ollama:/root/.ollama
environment:
- OLLAMA_KEEP_ALIVE=-1
- OLLAMA_NUM_PARALLEL=4
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
webui:
image: ghcr.io/open-webui/open-webui:main
container_name: open-webui
restart: unless-stopped
depends_on:
- ollama
ports:
- "127.0.0.1:8080:8080"
volumes:
- ./webui:/app/backend/data
environment:
- OLLAMA_BASE_URL=http://ollama:11434
- WEBUI_AUTH=True
- ENABLE_SIGNUP=False
Два важных момента. Порт проброшен на 127.0.0.1, а не наружу — снаружи будет только nginx. И ENABLE_SIGNUP=False: иначе любой, кто нашёл ваш адрес, зарегистрируется сам.
cd /opt/ai-server
docker compose up -d
docker compose exec ollama ollama pull qwen2.5:14b
Первый зарегистрировавшийся пользователь автоматически становится администратором — заходите сразу после старта и создавайте свой аккаунт, пока это не сделал кто-то другой.
ШАГ 2: NGINX И HTTPS
Открывать 8080 в интернет нельзя: там нет ни шифрования, ни защиты от перебора. Ставим nginx.
server {
server_name ai.example.com;
client_max_body_size 100M; # загрузка документов в RAG
location / {
proxy_pass http://127.0.0.1:8080;
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-Real-IP $remote_addr;
# стриминг ответов: без этого текст появляется рывками
proxy_buffering off;
proxy_read_timeout 600s;
}
listen 443 ssl;
}
Две строки, которые чаще всего забывают: proxy_buffering off — иначе ответ модели копится в буфере и вываливается пачкой вместо посимвольного стриминга, и proxy_read_timeout — иначе долгие ответы обрываются по таймауту.
certbot --nginx -d ai.example.com
ШАГ 3: ПОЛЬЗОВАТЕЛИ И РОЛИ
Open WebUI умеет разграничивать доступ из коробки. В админке настраивается:
- Роли — admin, user, pending. Новые аккаунты можно держать в pending до одобрения.
- Доступ к моделям — тяжёлую 70B оставить только части команды, остальным 8B.
- Группы — разные наборы моделей и промптов для отделов.
- История — у каждого своя, админ не видит чужие чаты по умолчанию.
ШАГ 4: RAG ПО ДОКУМЕНТАМ КОМПАНИИ
Самая ценная часть для бизнеса: модель отвечает на основе ваших регламентов, а не общих знаний из интернета.
В Open WebUI это раздел Workspace → Knowledge. Загружаете PDF, docx, markdown — система сама режет на чанки, считает эмбеддинги и кладёт в векторную базу. Дальше в чате указываете коллекцию через # и модель отвечает по ней.
Что подкрутить для качества:
| Параметр | Значение | Зачем |
|---|---|---|
| Chunk size | 800-1200 | слишком мелкие чанки теряют контекст |
| Chunk overlap | 100-200 | чтобы мысль не разрывалась между кусками |
| Top K | 4-6 | больше — шум, меньше — недобор фактов |
| Embedding-модель | multilingual | для русских документов обязательно |
Дефолтная англоязычная embedding-модель на русских документах работает заметно хуже — это первое, что стоит поменять.
ГРАБЛИ, НА КОТОРЫЕ НАСТУПАЮТ ВСЕ
- Модель выгружается между запросами. Первый ответ после паузы идёт минуту. Лечится
OLLAMA_KEEP_ALIVE=-1, модель остаётся в памяти. - Открытая регистрация. Забыли
ENABLE_SIGNUP=False— и вашим сервером пользуется весь интернет. - Диск кончился. Модели весят десятки гигабайт, история чатов и векторная база растут. Мониторьте место.
- Один запрос вешает всех. При
OLLAMA_NUM_PARALLEL=1команда стоит в очереди. Ставьте по числу пользователей, если памяти хватает. - Нет бэкапа. Папка
webuiсодержит всю историю и настройки. Потеряете — потеряете всё.
СКОЛЬКО ЭТО СТОИТ
Разовые вложения против подписки для команды на 20 человек:
| Статья | Своё железо | Облачная подписка |
|---|---|---|
| Старт | цена GPU-сервера | 0 |
| В месяц | электричество | 20 × тариф на пользователя |
| Через год | железо остаётся вашим | платите снова |
| Приватность | полная | по договору с вендором |
| Качество моделей | ниже топовых | лучшее на рынке |
Честный вывод: своё железо выигрывает на горизонте от года и там, где приватность критична. Если нужна максимальная модель здесь и сейчас — облако сильнее.
FAQ
Потянет ли сервер команду из 20 человек?
Если работают не все одновременно — да, одной 4090 хватает. При реальной параллельной нагрузке считайте по OLLAMA_NUM_PARALLEL и памяти: каждый параллельный слот требует своего KV-кэша.
Можно ли подключить и облачные модели тоже?
Да, Open WebUI умеет работать с любым OpenAI-совместимым API одновременно с Ollama. Удобная схема: приватное — локально, сложное — в облако.
Как обновлять?
docker compose pull && docker compose up -d. Данные в примонтированных папках, обновление их не трогает. Бэкап папки webui перед обновлением всё равно сделайте.
Работает ли с русскими документами в RAG?
Работает, но обязательно смените embedding-модель на мультиязычную в настройках. С дефолтной англоязычной качество поиска по русским текстам заметно падает.
