MAATRIX / Блог / Как подключить Open WebUI к OpenAI API

Как подключить Open WebUI к OpenAI API

Как подключить Open WebUI к OpenAI API

MAATRIX

Подключить Open WebUI к OpenAI API — это два поля в админ-панели, и ровно поэтому на нём буксуют часами: поля заполнены правильно, а список моделей пустой. Спотыкаются об одно и то же — забытый суффикс /v1, настройки, закэшированные в базе при первом старте, и 403 по стране, который переменной окружения не лечится. Разберём подключение по шагам, с проверкой ключа прямо с сервера.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Что именно вы подключаете

Open WebUI не считает ни одного токена сам. К внешнему API он делает два типа запросов: GET /v1/models, чтобы наполнить выпадающий список, и POST /v1/chat/completions со стримом SSE, когда вы жмёте «отправить». Всё подключение — дать ему базовый URL и Bearer-ключ; остальное производно от этих двух запросов, включая большинство поломок. Тот же слот принимает OpenRouter, ваш LiteLLM, vLLM или Groq.

Настроить можно в двух местах, и они конфликтуют:

  • Админ-панель → Настройки → Подключения → OpenAI API. Плюсом добавляется карточка: URL, ключ, поле фильтра моделей.
  • Переменные окружения: ENABLE_OPENAI_API=true (по умолчанию), OPENAI_API_BASE_URL и OPENAI_API_KEY для одного эндпоинта либо OPENAI_API_BASE_URLS и OPENAI_API_KEYS через точку с запятой для нескольких.

Чего коннектор не делает, чтобы вы не искали несуществующие настройки: не знает про Assistants и Responses API (только классический chat completions), не отправляет заголовки OpenAI-Organization и OpenAI-Project и не ведёт учёт расходов.

Подключение за пять шагов

Шаг 1. Ключ. На platform.openai.com → API keys → Create new secret key. Проектные ключи выглядят как sk-proj-..., старые — как sk-...; работают оба, секрет показывается один раз. Сразу пополните баланс: ключ валиден и с нулём на счёте, но первый же запрос вернёт 429 — не про частоту обращений, а про деньги.

Шаг 2. Проверка с сервера, а не с ноутбука. Ноутбук ходит в интернет одним маршрутом, сервер другим:

export OPENAI_API_KEY='sk-proj-...'
curl -s -o /dev/null -w "HTTP %{http_code}  connect %{time_connect}s  ttfb %{time_starttransfer}s\n" \
  -H "Authorization: Bearer $OPENAI_API_KEY" https://api.openai.com/v1/models

С лондонского VPS здоровый ответ такой: HTTP 200 connect 0.087s ttfb 0.31s. 401 — ключ, 403 — локация, таймаут — исходящий фаервол.

Шаг 3. Настоящий запрос. Список моделей отдаёт и ключ без квоты, поэтому проверяем генерацию:

curl -s https://api.openai.com/v1/chat/completions \
  -H "Authorization: Bearer $OPENAI_API_KEY" -H "Content-Type: application/json" \
  -d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"ping"}],"max_tokens":5}'

Шаг 4. Тот же тест изнутри контейнера — у Docker свои DNS и маршруты: docker exec open-webui curl -s -o /dev/null -w "%{http_code}\n" -H "Authorization: Bearer $OPENAI_API_KEY" https://api.openai.com/v1/models.

Шаг 5. Только теперь интерфейс. Админ-панель → Настройки → Подключения → OpenAI API → плюс. В поле URL строго https://api.openai.com/v1 — не https://api.openai.com и не со слэшем на конце. То же самое в compose:

    environment:
      - ENABLE_OPENAI_API=true
      - OPENAI_API_BASE_URL=https://api.openai.com/v1
      - OPENAI_API_KEY=${OPENAI_API_KEY}
      - ENABLE_OLLAMA_API=false
      - AIOHTTP_CLIENT_TIMEOUT=300
      - AIOHTTP_CLIENT_TIMEOUT_MODEL_LIST=10

Ключ держите в отдельном .env и закройте его: chmod 600 .env. В сам compose ключи не вписывайте — уедут в git.

Развернуть за пару минут

Готовый образ на VPS MAATRIX: NVMe, AMD EPYC, root-доступ. Локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Развернуть Open WebUI

Ключ работает в curl, а в интерфейсе моделей нет

Самая дорогая ловушка — PersistentConfig. Вся группа OPENAI_* читается только при первом старте контейнера, дальше значение живёт в таблице config файла /app/backend/data/webui.db, и база важнее окружения: вы правите compose, делаете docker compose up -d, а сервис ходит по старому адресу со старым ключом. Что там на самом деле — sqlite3 в образе нет, а Python есть:

docker exec open-webui python3 -c "import sqlite3,json; \
c=sqlite3.connect('/app/backend/data/webui.db'); \
d=json.loads(c.execute('select data from config order by id desc limit 1').fetchone()[0]); \
print(json.dumps(d.get('openai'),indent=1))"

Адрес в выводе не тот, что в compose — причина найдена. Лечится правкой в админ-панели либо ENABLE_PERSISTENT_CONFIG=False, у второго варианта есть цена: эти настройки перестают редактироваться из интерфейса.

Три остальные причины пустого списка:

  • Нет /v1 в адресе. Open WebUI сходит на https://api.openai.com/models, получит 404 и покажет пустоту без единой ошибки в интерфейсе. В docker logs open-webui при этом видно Connection error или строку с 404.
  • Рассинхрон списков. В OPENAI_API_BASE_URLS и OPENAI_API_KEYS элементы сопоставляются по позиции: два URL и один ключ, лишняя точка с запятой, пробел после разделителя — и второй эндпоинт получает пустой ключ, отвечая 401 при верных данных.
  • Мёртвый сосед. Список собирается со всех включённых коннекторов, один недоступный тормозит выдачу целиком. На опрос отводится около 10 секунд (AIOHTTP_CLIENT_TIMEOUT_MODEL_LIST); OpenAI укладывается в 300–400 мс, а забытый Ollama или упавший LiteLLM съедают весь бюджет.

403 из России: почему это не лечится переменными

Если сервер стоит в России, честный ключ вернёт вот такое тело ответа:

{"error":{"message":"Country, region, or territory not supported",
"type":"request_forbidden","code":"unsupported_country_region_territory"}}

Решение принимается по IP исходящего соединения, ещё до проверки ключа: ни заголовки, ни другой ключ на это не влияют. Вариантов ровно три:

  • Сервер сразу в поддерживаемой локации. Правильный путь: контейнер в Лондоне или Нью-Йорке ходит в OpenAI напрямую, без движущихся частей.
  • Отдельный API-прокси, а Open WebUI дома. В подключении вместо api.openai.com указывается свой домен, например https://gw.example.com/v1. Схему разбирали в статье «Как поднять API-прокси к OpenAI из России на сервере».
  • Исходящий прокси прямо в контейнереHTTPS_PROXY=http://10.8.0.2:3128 и NO_PROXY=localhost,127.0.0.1,host.docker.internal,litellm. Оговорка: HTTP-клиент Open WebUI подхватывает прокси из окружения не во всех вызовах, типичный итог — чат отвечает, а список моделей пустой. Надёжнее заворачивать трафик на уровне сети (WireGuard плюс правило маршрутизации для подсети Docker), а не переменными.

Честное предупреждение про деньги: пополнить баланс OpenAI картой российского банка нельзя — нужна зарубежная карта или посредник, эту задачу сервер не решает.

Мусор в списке, доступ к моделям и «это не chat-модель»

Как только подключение заработало, в селекторе окажется несколько десятков позиций: рядом с нужными моделями — whisper-1, tts-1, dall-e-3, text-embedding-3-large, omni-moderation-latest, старые снапшоты. /v1/models возвращает всё, к чему у ключа есть доступ, фильтровать по типу эндпоинт не умеет. Выберите такую модель в чате, и OpenAI ответит:

{"error":{"message":"This is not a chat model and thus not supported in
the v1/chat/completions endpoint.","type":"invalid_request_error",
"param":"model","code":null}}

Лечится полем Model IDs в карточке подключения: перечислите две-три рабочие модели — одну дешёвую на 90 % запросов и одну сильную, — и в списке останутся только они. Актуальные идентификаторы у вашего ключа даёт curl -s -H "Authorization: Bearer $OPENAI_API_KEY" https://api.openai.com/v1/models | jq -r '.data[].id' | sort: линейка OpenAI меняется несколько раз в год, имена из чужих статей быстро устаревают.

Отдельная ошибка, которую путают с опечаткой:

{"error":{"message":"The model `gpt-4o` does not exist or you do not have
access to it.","type":"invalid_request_error","code":"model_not_found"}}

Модель существует, доступа нет у ключа: у проектных sk-proj-... он настраивается в platform.openai.com → Project → Limits → Model access.

Дальше — права внутри Open WebUI. В разделе «Модели» у каждой позиции есть видимость: private, public или доступ по группам; дорогую модель разумно открыть двум-трём людям, остальным оставить дешёвую. Следите, чтобы не был переключён BYPASS_MODEL_ACCESS_CONTROL — он отключает эту проверку целиком. Если каждый платит за себя, включите ENABLE_DIRECT_CONNECTIONS=true: пользователь добавляет собственный ключ в своих настройках, минус — чужие ключи тоже лягут в вашу базу.

Деньги, лимиты и безопасность ключа

Ошибка 429 бывает двух видов, и лечатся они противоположно. Первая — про деньги: You exceeded your current quota, please check your plan and billing details, код insufficient_quota; пополняйте счёт, ждать бесполезно. Вторая — про скорость: Rate limit reached for gpt-4o-mini in organization org-XXXX on tokens per min (TPM): Limit 200000, Used 199431, Requested 1200; здесь достаточно подождать, а системно — поднять tier. Различить их можно только в docker logs open-webui: в чате обе выглядят одинаково безлико.

Главное ограничение: Open WebUI не считает деньги вообще — ни по пользователям, ни по моделям, ни лимитов, ни алертов. Если расходы нужно делить, между ним и OpenAI ставится LiteLLM с таким config.yaml:

model_list:
  - model_name: gpt-4o-mini
    litellm_params:
      model: openai/gpt-4o-mini
      api_key: os.environ/OPENAI_API_KEY
general_settings:
  master_key: sk-master-change-me
  database_url: postgresql://litellm:pass@postgres:5432/litellm

В Open WebUI тогда указывается http://litellm:4000/v1 и виртуальный ключ, выданный через /key/generate с параметром max_budget. Прослойка даёт бюджеты и статистику по ключам — ценой ещё одного сервиса, который надо обновлять и бэкапить. Подробности в статье «Как установить и настроить LiteLLM на VPS».

Про безопасность коротко. Ключ хранится в webui.db в открытом виде, и docker exec open-webui env печатает его на экран — не вставляйте вывод в чужие тикеты. Бэкап каталога /app/backend/data содержит рабочий ключ, поэтому архив шифруйте. Порт наружу не публикуйте: -p 127.0.0.1:3000:8080 плюс HTTPS через nginx.

Какой сервер взять в MAATRIX под эту схему

Когда модели считает OpenAI, требования к железу падают до минимума: ни GPU, ни мощного процессора, ни диска под веса. Open WebUI здесь — обычное веб-приложение поверх SQLite.

СценарийvCPURAMДиск NVMe
1–3 человека, только внешний API24 ГБ40 ГБ
5–15 человек, документы и веб-поиск48 ГБ80 ГБ
Команда, LiteLLM и PostgreSQL рядом4–88–16 ГБ120 ГБ

Честный минимум — 2 vCPU, 4 ГБ, 40 ГБ. Контейнер в простое держит 600–900 МБ, и на двух гигабайтах стартует и первые дни выглядит нормально. Ломается позже: при первой загрузке PDF в базу знаний подтягивается модель эмбеддингов, память уходит в потолок, и контейнер перезапускается на глазах у коллег. Комфортный вариант — 4 vCPU и 8 ГБ: помещается всё, включая LiteLLM с бюджетами и PostgreSQL вместо SQLite. Трафика схема почти не ест.

Локация — Великобритания, Лондон. Британский IP входит в список поддерживаемых OpenAI: 403 unsupported_country_region_territory вам не грозит, а значит, не нужны ни прокси, ни VPN, ни разбирательства с HTTPS_PROXY из четвёртой секции. Вторая причина — арифметика задержек. Время до первого токена складывается из двух отрезков: пользователь → ваш сервер и сервер → api.openai.com. Первый из Москвы до Лондона — порядка 45–60 мс против 110–130 мс до Нью-Йорка, и он умножается на каждое действие в интерфейсе: открытие чата, переключение модели, загрузку файла. Второй из Лондона — те самые 87 мс из шага 2, на фоне секунды раздумий модели это не видно. Третья причина — юрисдикция и GDPR-соседство, если в переписку попадают данные клиентов. Франция равноценна для пользователей в континентальной Европе; Нью-Йорк берут под сервисы, пускающие только американские адреса. Российская локация здесь не подходит принципиально — она оправдана, когда все модели локальные.

Оплата — картами российских банков, по СБП, криптовалютой или токеном MAAT; зарубежная карта для сервера в Лондоне не нужна. Установка с нуля разобрана в статье «Как установить и настроить Open WebUI на VPS», поломки — в «Open WebUI на сервере: частые ошибки и решения».

Развернуть за пару минут

Готовый образ на VPS MAATRIX: NVMe, AMD EPYC, root-доступ. Локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Развернуть Open WebUI

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Частые вопросы

Какой именно URL вводить в подключении?

Строго https://api.openai.com/v1 — с суффиксом /v1 и без слэша на конце. Без /v1 Open WebUI получит 404 на запрос списка моделей и покажет пустой селектор без единой ошибки в интерфейсе.

Поменял OPENAI_API_KEY в compose, а сервис использует старый ключ.

Штатное поведение PersistentConfig: значение скопировалось в таблицу config базы webui.db при первом запуске, дальше приоритет у базы. Меняйте ключ в «Админ-панель → Настройки → Подключения» либо добавьте ENABLE_PERSISTENT_CONFIG=False и пересоздайте контейнер.

Можно ли ограничить расходы прямо в Open WebUI?

Нет, он не считает деньги ни по пользователям, ни по моделям. Ограничения ставятся снаружи: лимиты проекта на platform.openai.com либо LiteLLM между Open WebUI и OpenAI с виртуальными ключами и параметром max_budget.

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.