Open WebUI на сервере: частые ошибки и решения
Open WebUI ставится одной командой docker run, а ломается по короткому и предсказуемому списку: белый экран вместо интерфейса, пустой селектор моделей, «Account Activation Pending» у коллеги, ответ одним куском через минуту, кончившийся диск на третьей неделе. Почти каждая из этих ошибок Open WebUI лечится одной переменной окружения, строкой в nginx или запросом к базе — ниже разбор с реальными строками из логов и консоли браузера.
Содержание
- Быстрая диагностика: три слоя и четыре команды
- Интерфейс не открывается: порты, фаервол и падающий контейнер
- Пустой список моделей и «Server Connection Error»
- Вход не работает: pending, 401 и потерянный админ
- Стриминг обрывается, чат не обновляется, приходит 524
- Правки не применяются, диск кончился, обновление сломало базу
- Какой сервер брать под Open WebUI в MAATRIX
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Быстрая диагностика: три слоя и четыре команды
Open WebUI — это три слоя, и поломка почти всегда живёт ровно в одном: контейнер, бэкенды моделей (Ollama, внешний OpenAI-совместимый эндпоинт) и транспорт до браузера (прокси, WebSocket, куки). Определяйте слой, а не гуглите текст ошибки целиком.
docker ps --filter name=open-webui --format "{{.Status}}\t{{.Ports}}"
curl -s -w " HTTP %{http_code}\n" http://127.0.0.1:3000/health
docker logs --tail 300 open-webui 2>&1 | grep -iE "error|traceback|refused"
docker exec open-webui env | grep -E "OLLAMA|OPENAI|WEBUI"
Здоровая машина отвечает Up 6 hours (healthy) 127.0.0.1:3000->8080/tcp и {"status":true} HTTP 200. Если health отдаёт 200, а в браузере пусто — виноват третий слой. Пока в логах нет строки INFO: Application startup complete., браузер честно получает белый экран: идут миграции и скачивание модели эмбеддингов, на слабой машине три-пять минут. Последняя команда самая недооценённая — она показывает, что контейнер получил на самом деле, а не что вы написали в compose.
Интерфейс не открывается: порты, фаервол и падающий контейнер
Внутри контейнера Open WebUI всегда слушает 8080, наружу его принято отдавать на 3000: -p 127.0.0.1:3000:8080. Запись -p 8080:3000 отработает без ошибок, только за портом никого не будет (ss -ltnp | grep 3000). Если порт занят, докер отвечает дословно: Bind for 0.0.0.0:3000 failed: port is already allocated.
Дальше ловушка, на которой обжигаются почти все. UFW не защищает опубликованные порты Docker. Пишете ufw deny 3000/tcp, видите правило в ufw status, а сервис открыт всему интернету: докер добавляет свои правила в цепочку DOCKER-USER, и трафик идёт мимо цепочек ufw (iptables -L DOCKER-USER -n -v). Решение не в борьбе с iptables: не публикуйте порт вообще — слушайте 127.0.0.1:3000, наружу отдавайте только 443 через nginx. Открытый Open WebUI сканеры находят за часы, и первый зашедший станет вашим администратором.
Отдельный симптом — Restarting (137) в выводе docker ps. Код 137 это SIGKILL: в девяти случаях из десяти процесс убило ядро за нехватку памяти, и проверяется это одной командой — docker inspect --format='{{.State.OOMKilled}} {{.State.ExitCode}}' open-webui. Ответ true 137 закрывает вопрос. Типовой случай — 2 ГБ на VPS, где рядом крутится Ollama с загруженной моделью.
Последняя причина зависшего старта — закрытый исходящий трафик: при первом запуске приложение тянет модель эмбеддингов sentence-transformers/all-MiniLM-L6-v2 с huggingface.co и упирается в:
OSError: We couldn't connect to 'https://huggingface.co' to load the files,
and couldn't find them in the cached files.
Лечится зеркалом HF_ENDPOINT=https://hf-mirror.com либо переводом эмбеддингов на локальный движок (RAG_EMBEDDING_ENGINE=ollama). Есть ещё OFFLINE_MODE=true, но он запрещает загрузку любых моделей — встроенный RAG после него не заработает.
Развернуть за пару минут
Готовый образ на VPS MAATRIX: NVMe, AMD EPYC, root-доступ. Локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Развернуть Open WebUIПустой список моделей и «Server Connection Error»
Вход выполнен, а селектор моделей пуст или при отправке сообщения всплывает красное уведомление о проблеме соединения. В логах при этом:
aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host
127.0.0.1:11434 ssl:default [Connect call failed ('127.0.0.1', 11434)]
Внутри контейнера 127.0.0.1 указывает на сам контейнер, поэтому Ollama на хосте по нему не найдётся никогда. Берём адрес docker-моста из ip -4 addr show docker0 | grep inet (обычно 172.17.0.1) и ставим OLLAMA_BASE_URL=http://172.17.0.1:11434.
Второе условие: Ollama по умолчанию слушает только петлю, ей нужен оверрайд systemctl edit ollama.service со строкой Environment="OLLAMA_HOST=0.0.0.0:11434". После перезапуска в ss -ltnp | grep 11434 должно появиться LISTEN 0 4096 *:11434.
Оговорка, которую мануалы пропускают: у Ollama нет авторизации вообще, поэтому наружу 11434 не публикуют, а в фаерволе открывают ровно на сеть докера. Связь изнутри контейнера удобно проверять питоном (curl в образе может отсутствовать): docker exec open-webui python -c "import urllib.request as u; print(u.urlopen('http://172.17.0.1:11434/api/tags').read()[:120])".
У внешних OpenAI-совместимых эндпоинтов свои грабли. Базовый URL обязан включать /v1: без суффикса получите 404 и пустой список. Адреса перечисляются в OPENAI_API_BASE_URLS через точку с запятой, и ключи в OPENAI_API_KEYS должны идти в том же порядке — рассинхрон даёт 401 при верных ключах. Если список моделей открывается по двадцать-тридцать секунд, виноват один мёртвый эндпоинт: в ветке 0.6.x лечится переменной AIOHTTP_CLIENT_TIMEOUT_MODEL_LIST=10. И отдельный класс — 403 про неподдерживаемую страну: это не конфиг, а IP сервера, лечится только локацией.
Вход не работает: pending, 401 и потерянный админ
Первый зарегистрированный аккаунт становится администратором, все следующие получают роль из DEFAULT_USER_ROLE со значением по умолчанию pending. Поэтому коллега регистрируется и видит Account Activation Pending — Contact Admin for WebUI Access. Это не поломка: одобряйте людей в админ-панели (раздел Users) либо выставьте DEFAULT_USER_ROLE=user, а когда все свои зашли — закрывайте регистрацию через ENABLE_SIGNUP=false.
Второй симптом — «всех разлогинило, а клиенты по API получают 401». Виноват WEBUI_SECRET_KEY, которым подписываются JWT сессий: если он не задан явно, то генерируется при первом старте в /app/backend/data/.webui_secret_key. Пересоздали volume, переехали на другую машину, поменяли значение — все токены недействительны. Задайте ключ один раз через openssl rand -hex 32 и держите в бэкапе рядом с базой.
Третий случай, самый нервный: потерян пароль администратора, а почта для восстановления не настроена. Чинится в SQLite напрямую — хеш берём библиотекой из контейнера, базу правим на остановленном сервисе:
docker exec open-webui python -c "import bcrypt; print(bcrypt.hashpw(b'Пароль123', bcrypt.gensalt()).decode())"
docker stop open-webui
DB=/var/lib/docker/volumes/open-webui/_data/webui.db
sqlite3 "$DB" "UPDATE auth SET password='ХЕШ_2b12' WHERE email='admin@example.com';"
sqlite3 "$DB" "UPDATE user SET role='admin' WHERE email='admin@example.com';"
docker start open-webui
Четвёртый симптом — бесконечный цикл входа: пароль принят, страница мигает и снова просит логин. Так проявляется кука сессии с флагом Secure, которую браузер не хранит на обычном http — лечится доведённым до конца HTTPS и переменной WEBUI_URL=https://chat.example.com. И про WEBUI_AUTH=False с форумов: он снимает авторизацию полностью, каждый знающий адрес получает права админа.
Стриминг обрывается, чат не обновляется, приходит 524
Интерфейс использует два транспорта, и ломаются они по-разному: токены ответа идут потоком SSE, события — через socket.io по пути /ws/socket.io/. Ответ пришёл одним куском в конце: это SSE и буферизация в nginx. Чат «залипает» и оживает только после F5: упал WebSocket, и в консоли браузера лежит
WebSocket connection to 'wss://chat.example.com/ws/socket.io/?EIO=4&transport=websocket'
failed: Error during WebSocket handshake: Unexpected response code: 400
Секция nginx на оба случая:
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_buffering off;
proxy_read_timeout 600s;
client_max_body_size 200m;
}
Применяем через nginx -t && systemctl reload nginx. Ровно 60 секунд до ошибки в логе — подпись дефолтного proxy_read_timeout, а client_max_body_size снимает 413 при загрузке крупных PDF. Если домен проксируется через Cloudflare в оранжевом режиме, помните про потолок в 100 секунд и ошибку 524 — для длинных генераций держите домен в режиме DNS-only.
Отдельная засада у тех, кто решил «ускорить» сервис воркерами: при UVICORN_WORKERS=4 события теряются — сообщение ушло одному воркеру, сокет пользователя висит на другом, ответ пишется в базу, но виден только после F5. Нужна общая шина: WEBSOCKET_MANAGER=redis и WEBSOCKET_REDIS_URL=redis://127.0.0.1:6379/1. Честно: команде из 5–20 человек воркеры не нужны вовсе.
Правки не применяются, диск кончился, обновление сломало базу
Самая обидная ошибка второй недели: правите переменную в compose.yaml, перезапускаете контейнер — и ничего не меняется. При первом запуске Open WebUI копирует часть настроек из окружения в таблицу config внутри базы, и дальше приоритет у базы. Что там реально лежит, покажет sqlite3 /var/lib/docker/volumes/open-webui/_data/webui.db "SELECT data FROM config ORDER BY id DESC LIMIT 1;" | python3 -m json.tool. Решения два: менять такие параметры в админ-панели либо выставить ENABLE_PERSISTENT_CONFIG=False, чтобы окружение было главнее — правда, тогда они перестают редактироваться из интерфейса.
Второе — диск. Смотрите не общий объём, а разбивку docker exec open-webui du -sh /app/backend/data/* | sort -h. Типичная картина там, где полгода работали с документами: webui.db — 1,4 МБ, cache — 340 МБ, uploads — 1,1 ГБ, vector_db — 1,6 ГБ. Векторный индекс сопоставим по объёму с исходниками, а сами исходники остаются лежать рядом в uploads: удаление документа из интерфейса не всегда вычищает файл с диска. Плюс логи докера, у json-file лимита по умолчанию нет: --log-opt max-size=50m --log-opt max-file=3.
Третье — database is locked: SQLite не любит параллельную запись, и на десятке активных пользователей это вылезает регулярно. Переезд делается переменной DATABASE_URL=postgresql://openwebui:ПАРОЛЬ@127.0.0.1:5432/openwebui, но штатного переноса данных из SQLite в Postgres в проекте нет — либо чистая база, либо community-скрипты. Решайте про СУБД на старте.
Четвёртое — обновления. Тег :main меняется под вами, и однажды после планового docker pull сервис не поднимется — фиксируйте версию, например ghcr.io/open-webui/open-webui:v0.6.18. Безопасный порядок:
docker stop open-webui
tar czf /var/backups/openwebui-$(date +%F).tgz -C /var/lib/docker/volumes/open-webui/_data .
docker pull ghcr.io/open-webui/open-webui:main
docker rm open-webui && docker run -d ... # ваша обычная команда запуска
Главное про откат: миграции alembic едут только вперёд. Вернёте старый образ на уже мигрированную базу — получите alembic.util.exc.CommandError: Can't locate revision identified by 'a1b2c3d4e5f6' или ошибку SQLAlchemy про отсутствующую колонку. Откат — это всегда пара: старый тег образа плюс восстановленный из архива каталог данных. Поэтому не вешайте на Open WebUI автообновление вроде Watchtower.
Какой сервер брать под Open WebUI в MAATRIX
Сам Open WebUI — лёгкое веб-приложение: чат, история, роли, проксирование запросов. Тяжёлым он становится в двух местах: когда на той же машине считает модели Ollama и когда вы активно пользуетесь базой знаний.
| Сценарий | vCPU | RAM | Диск NVMe |
|---|---|---|---|
| Интерфейс к внешним API (OpenAI, Anthropic, свой LiteLLM) | 2 | 4 ГБ | 40 ГБ |
| Интерфейс плюс Ollama, модели до 8B | 4 | 8 ГБ | 80 ГБ |
| Команда, RAG, PostgreSQL рядом, модели до 14B | 8 | 16 ГБ | 160–200 ГБ |
Минимум, на котором это честно работает — 2 vCPU, 4 ГБ, 40 ГБ, и только если модели считаются не здесь. Контейнер в простое держит 600–900 МБ RSS, после первого обращения к базе знаний — 1,2–1,5 ГБ. На двух гигабайтах вы получите тот самый Restarting (137) из второй секции.
Комфортный вариант — 8 vCPU и 16 ГБ: помещается всё, включая Ollama с моделью на 8–14 миллиардов параметров и PostgreSQL вместо SQLite. Диск кончается первым: 8B в квантовании Q4 занимает около 4,7 ГБ, 14B — порядка 9 ГБ, и три-четыре модели вместе с индексом съедают 80 ГБ.
Локация — Великобритания (Лондон). Open WebUI это интерактивный интерфейс, а не фоновый демон: задержка чувствуется на каждом действии — открытии чата, переключении модели, загрузке файла. Из Москвы до Лондона порядка 45–60 мс против 110–130 мс до Нью-Йорка. При этом британский IP спокойно принимают OpenAI, Anthropic и Google, так что 403 про неподдерживаемую страну не грозит. Франция — равноценная альтернатива для пользователей в ЕС, Нью-Йорк берут под сервисы для американских адресов, а российская локация оправдана, когда все модели локальные и 152-ФЗ важнее задержки.
Оплата — картами российских банков, по СБП, криптовалютой или токеном MAAT; зарубежная карта для сервера в Лондоне не нужна. Связка Ollama и Open WebUI разворачивается из каталога приложений, а установку с нуля мы разбирали в соседних статьях «Open WebUI на Ubuntu 24.04: пошаговая установка» и «Как установить и настроить Open WebUI на VPS». Сомневаетесь в конфигурации — опишите сценарий: сколько человек, какие модели, есть ли база знаний.
Развернуть за пару минут
Готовый образ на VPS MAATRIX: NVMe, AMD EPYC, root-доступ. Локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Развернуть Open WebUIОбсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Частые вопросы
Почему я изменил переменную окружения, а Open WebUI её игнорирует?
Часть настроек при первом старте копируется в таблицу config внутри базы, и дальше приоритет у неё. Меняйте такие параметры в админ-панели либо выставьте ENABLE_PERSISTENT_CONFIG=False.
Открыл 11434 наружу, чтобы Open WebUI видел Ollama. Это нормально?
Нет: у Ollama нет авторизации вообще, и публичный 11434 означает, что ваш процессор считает чужие запросы. Пусть она слушает 0.0.0.0 внутри машины, а фаервол пускает только сеть докера: ufw allow from 172.17.0.0/16 to any port 11434 proto tcp.
Можно ли откатиться на предыдущую версию, если обновление сломало сервис?
Только вместе с данными: миграции alembic необратимы, старый образ на новой схеме падает с Can't locate revision identified by .... Откат — это старый тег образа плюс каталог /app/backend/data из архива, снятого до обновления.
Нужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.