Настройка веб-интерфейса для LLM (Open WebUI)
Модель на сервере уже отвечает через API — мы разобрали это в предыдущей статье серии на примере srv-ai01. Но curl в терминале не годится для повседневной работы: нет истории диалогов, нельзя переключаться между моделями одним кликом, неудобно загружать документы для анализа. Именно эти задачи закрывает Open WebUI — open-source веб-интерфейс, который изначально писался под Ollama и сегодня умеет работать практически с любым LLM-бэкендом, включая OpenAI-совместимые API. Внешне он напоминает интерфейс популярных облачных чат-ботов, но крутится полностью на твоём железе, а все диалоги остаются внутри сети itpages.lab.local.
В этой статье поднимем Open WebUI на том же сервере srv-ai01, где уже работает Ollama, настроим доступ по HTTPS через реверс-прокси и разберём базовую администрирование: пользователей, роли и подключение внешних моделей.
Подготовка сервера
Open WebUI проще всего разворачивать в Docker — так не нужно вручную тянуть Python-зависимости и следить за версиями. Проверь, установлен ли Docker, и поставь его, если нет:
docker --version
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
После добавления пользователя в группу docker перезайди в сессию (или выполни newgrp docker), иначе команды docker будут требовать sudo каждый раз.
Запуск Open WebUI в Docker
Поскольку Ollama уже установлена на srv-ai01 напрямую и слушает порт 11434, самый простой вариант — запустить Open WebUI в контейнере, который обращается к Ollama по адресу хоста:
docker run -d \
--name open-webui \
-p 3000:8080 \
--add-host=host.docker.internal:host-gateway \
-e OLLAMA_BASE_URL=http://host.docker.internal:11434 \
-v open-webui-data:/app/backend/data \
--restart always \
ghcr.io/open-webui/open-webui:main
Разберём ключевые флаги. Том open-webui-data сохраняет базу данных с пользователями, чатами и настройками — без него всё удалится при пересоздании контейнера. Флаг —restart always поднимает контейнер автоматически после перезагрузки сервера. Переменная OLLAMA_BASE_URL указывает, где искать Ollama — если бы Ollama тоже работала в Docker на той же машине, вместо host.docker.internal использовали бы имя контейнера в общей сети.
Проверь, что контейнер запустился и не падает в перезапуск:
docker ps
docker logs -f open-webui
Первый запуск занимает около минуты — контейнер инициализирует базу данных. После этого интерфейс доступен по адресу http://192.168.10.20:3000 с любой машины в сети 192.168.10.0/24.
Первый вход и создание администратора
Открой адрес сервера в браузере. Первый зарегистрированный пользователь автоматически получает роль администратора — поэтому создавай учётку администратора сразу сам, не давая ссылку коллегам до этого момента. Введи имя, email и пароль в форме регистрации. Все последующие пользователи по умолчанию попадают в очередь на подтверждение — это удобная защита от случайного открытия сервиса всем желающим в сети.
Подключение моделей
После входа Open WebUI автоматически подтягивает список моделей, уже загруженных в Ollama, — они появятся в выпадающем меню выбора модели в верхней части чата. Если список пуст, зайди в Settings → Admin Settings → Connections и проверь, что адрес Ollama указан верно и доступен из контейнера.
Загрузить новую модель можно прямо из интерфейса, не заходя в консоль сервера: Settings → Models → Pull a model from Ollama.com, вводишь имя модели (например mistral:7b) и нажимаешь скачать. Это удобно для нетехнических коллег, которым не нужно давать доступ к терминалу сервера ради установки новой модели.
Настройка HTTPS через реверс-прокси
Открывать чат по чистому HTTP даже во внутренней сети — плохая привычка, особенно если позже кто-то из коллег будет заходить через VPN. Поставь Caddy как реверс-прокси с автоматическим TLS-сертификатом — для внутреннего домена proще всего использовать самоподписанный сертификат или свой внутренний CA:
sudo apt install -y caddy
Пропиши конфигурацию в /etc/caddy/Caddyfile:
chat.itpages.lab.local {
reverse_proxy localhost:3000
tls internal
}
Перезапусти Caddy и добавь запись в локальный DNS (или в /etc/hosts на клиентских машинах, если внутреннего DNS-сервера пока нет):
sudo systemctl restart caddy
# 192.168.10.20 chat.itpages.lab.local
Теперь чат доступен по https://chat.itpages.lab.local, а прямой доступ к порту 3000 стоит закрыть в брандмауэре снаружи хоста, оставив его только для локального Caddy.
Загрузка документов и RAG
Одна из сильных сторон Open WebUI — встроенная поддержка Retrieval-Augmented Generation прямо из коробки. Загрузи документ через иконку скрепки в чате (поддерживаются PDF, txt, markdown, docx и другие форматы) — интерфейс автоматически разобьёт его на фрагменты, посчитает эмбеддинги и сохранит в локальную векторную базу. После этого можно задавать вопросы по содержимому документа, и модель будет отвечать, опираясь на релевантные фрагменты, а не только на свои общие знания.
Модель эмбеддингов по умолчанию тоже настраивается в Settings → Documents — можно оставить встроенную, а можно указать отдельную модель через Ollama, если нужна более высокая точность поиска для специфичных текстов на русском языке.
Веб-поиск и инструменты внутри чата
Open WebUI умеет не только отвечать из знаний модели, но и дополнять ответы результатами веб-поиска — это полезно, когда вопрос касается свежих событий, а локальная модель обучена на данных до определённой даты. Включается это в Settings → Web Search: выбираешь провайдера поиска (например, DuckDuckGo, который не требует ключа API, либо SearXNG, если хочешь держать поисковый движок тоже у себя) и активируешь тумблер. После включения в чате появляется значок глобуса — при его активации модель сначала выполнит поиск, соберёт релевантные страницы и только потом сформирует ответ с опорой на найденные источники.
Для внутренней инфраструктуры без выхода в интернет разумнее поднять SearXNG отдельным контейнером в той же сети и указать его как источник — тогда даже поисковые запросы не покидают периметр itpages.lab.local:
docker run -d --name searxng -p 8888:8080 --restart always \
-v searxng-data:/etc/searxng \
searxng/searxng
Настройка через переменные окружения
Помимо адреса Ollama, Open WebUI поддерживает десятки переменных окружения для тонкой настройки поведения без захода в интерфейс. Например, можно сразу отключить открытую регистрацию и задать имя инстанса при первом запуске:
docker run -d \
--name open-webui \
-p 3000:8080 \
--add-host=host.docker.internal:host-gateway \
-e OLLAMA_BASE_URL=http://host.docker.internal:11434 \
-e WEBUI_NAME="IT-Pages AI" \
-e ENABLE_SIGNUP=false \
-v open-webui-data:/app/backend/data \
--restart always \
ghcr.io/open-webui/open-webui:main
Такой подход удобен, если разворачиваешь конфигурацию не вручную, а через Ansible или другой инструмент автоматизации — все настройки безопасности фиксируются в коде развёртывания, а не в кликах по интерфейсу, которые легко забыть повторить на новом сервере.
Обновление контейнера
Проект развивается быстро, новые версии выходят регулярно с исправлениями и новыми функциями. Обновление сводится к пересозданию контейнера с той же командой запуска — данные при этом не теряются, поскольку живут в отдельном томе:
docker pull ghcr.io/open-webui/open-webui:main
docker stop open-webui
docker rm open-webui
# затем повторяем исходную команду docker run
Перед обновлением на проде стоит проверить changelog на предмет breaking changes — иногда меняется формат хранения настроек, и после апдейта может понадобиться повторно указать некоторые параметры через интерфейс.
Доступ с мобильных устройств
Open WebUI поддерживает установку как Progressive Web App — открой чат в мобильном браузере по адресу https://chat.itpages.lab.local, и большинство браузеров предложат добавить его на домашний экран. После установки интерфейс ведёт себя как обычное приложение, включая офлайн-кэширование статики, хотя сами запросы к модели, разумеется, требуют подключения к сети — либо через VPN, если сотрудник работает вне офиса, либо в пределах Wi-Fi сети itpages.lab.local.
Управление пользователями и группами
В разделе Admin Panel → Users администратор видит всех зарегистрированных пользователей и может менять им роль: user, admin или pending. Через группы удобно ограничивать доступ к конкретным моделям — например, тяжёлую модель на 70B параметров имеет смысл открыть только части команды, чтобы избежать очередей на GPU сервера srv-gpu01, а остальным оставить модель полегче.
Каждой группе можно назначить не только список разрешённых моделей, но и ограничение по функциям — например, запретить веб-поиск для группы стажёров или отключить возможность загрузки документов, если это не требуется по роли. Настройки прав живут в Admin Panel → Groups, где ты создаёшь группу, добавляешь в неё пользователей и настраиваешь permissions отдельным чек-листом: доступ к чату, к загрузке файлов, к созданию собственных промптов и так далее.
Мониторинг нагрузки
Когда сервисом пользуется больше одного человека, полезно понимать, насколько загружен GPU в моменте. Прямо на сервере это удобно смотреть командой nvidia-smi в режиме постоянного обновления:
watch -n 2 nvidia-smi
Если видно, что видеопамять регулярно упирается в потолок и запросы начинают выстраиваться в очередь, это сигнал либо перейти на менее прожорливую модель, либо добавить в конфигурацию второй GPU-сервер и распределить нагрузку — что мы подробно разберём в статье про MLOps-пайплайн ближе к концу серии.
Резервное копирование
Вся история чатов, пользователи и настройки хранятся в томе open-webui-data. Регулярно снимай с него бэкап — потеря этого тома означает потерю всей истории переписки и учётных записей:
docker run --rm -v open-webui-data:/data -v $(pwd):/backup alpine \
tar czf /backup/open-webui-backup-$(date +%F).tar.gz -C /data .
Такую команду удобно повесить в cron на еженедельный запуск, складывая архивы в отдельную папку с ротацией старых копий.
Частые ошибки и как их избежать
- Open WebUI не видит модели Ollama. Чаще всего причина в неверном адресе в OLLAMA_BASE_URL — контейнер не может обратиться к сервису на хосте напрямую по localhost, нужен либо host.docker.internal с флагом host-gateway, либо общая docker-сеть с Ollama, если она тоже в контейнере.
- Открытый доступ без ограничения регистрации. Если оставить публичную регистрацию включённой в сети, где сервис доступен многим, кто угодно сможет создать себе аккаунт. Отключи открытую регистрацию в Admin Settings после того, как заведёшь нужных пользователей, либо держи очередь подтверждений включённой.
- Потеря данных при пересоздании контейнера. Если запустить docker run без именованного тома -v, все чаты и пользователи исчезнут при следующем docker rm. Всегда монтируй постоянный том под /app/backend/data и делай резервные копии.
Что дальше
Тема ИИ-инструментов быстро развивается — вот соседние практические темы серии: