Запуск из исходного кода для разработки

Разберём локальный запуск Open WebUI из исходного кода: frontend и backend, отдельные данные, адреса и порты. Внесём небольшую правку и проверим dev reload.

После урока вы сможете

  • Отличить разработку Open WebUI от обычной установки для чата
  • Подготовить два локальных процесса на закреплённой версии исходников
  • Отделить dev-данные и ключ от рабочего экземпляра
  • Проверить небольшую правку интерфейса и различать UI, API и ответ модели

Проверяемый результат: Вы сможете подготовить отдельную локальную среду разработки Open WebUI, а при выполнении в своей разрешённой среде проверить правку интерфейса и объяснить путь запроса к backend и модели.

Допустим, вы хотите проверить небольшую собственную правку в Open WebUI: добавить к существующей подписи нового чата метку · dev, увидеть её в браузере, а затем вернуть исходную строку. Для такой задачи нужны закреплённые исходники, два отдельных локальных процесса и свой лабораторный экземпляр с отдельными данными и ключом; готовая языковая модель для этой проверки не требуется.

Разберём один маршрут для нативной Ubuntu 24.04 x86_64, где в терминале Bash уже доступны нужные версии Git, Node.js, npm и Python 3.11. Команды и фрагменты кода ниже сверены с закреплёнными исходниками выпуска v0.12.3 и проверены статически: установка пакетов, запуск серверов разработки, обновление интерфейса и работа модели при подготовке этого текста не выполнялись, поэтому все наблюдения дальше описаны как ориентиры для вашей собственной проверки.

Что должно работать, чтобы увидеть свою правку

Зачем ради одной короткой метки · dev в боковой панели запускать сразу две программы и почему для этого не нужна модель? В режиме разработки интерфейс и серверная часть разделены, чтобы вы могли править файлы на диске и сразу проверять результат без полной пересборки готового пакета или контейнера.

Когда вы просто пользуетесь приложением для переписки с моделью, исходный код вам не нужен: для этого проще и надёжнее подходят обычная установка через Docker Compose или запуск пакета Open WebUI через Python. Не заменяет исходники и готовый контейнерный образ с тегом :dev: как отмечается в официальном руководстве по разработке Open WebUI, такой образ позволяет познакомиться с предрелизной сборкой, но не даёт редактируемого дерева исходного кода и живого обновления компонентов.

При локальной разработке из исходников роли распределяются между тремя участниками:

  • Сервер разработки интерфейса (frontend) работает на базе SvelteKit и сборщика Vite. Он читает исходные файлы компонентов, отдаёт страницу браузеру на адресе http://127.0.0.1:5173 и отслеживает изменения в коде интерфейса.
  • Прокси-маршрутизатор внутри Vite принимает от браузера запросы к серверному API и WebSocket-соединениям на том же порту 5173 и перенаправляет их серверной части. В закреплённой версии src/lib/constants.ts базовый адрес WEBUI_BASE_URL оставлен пустым, поэтому браузер отправляет запросы по относительным путям к своему же источнику http://127.0.0.1:5173, а правила в vite.config.ts пересылают их на адрес из WEBUI_BACKEND_URL. Старые примеры, где браузер всегда обращается напрямую к порту 8080 в обход Vite, к этому выпуску переносить не нужно.
  • Серверная часть (backend) работает на Python и FastAPI по адресу http://127.0.0.1:8080. Она отвечает за конфигурацию, создание учётной записи, проверку входа и хранение базы данных. Без работающего backend и успешного входа в аккаунт интерфейс не откроет рабочую область с боковой панелью, где находится нужная кнопка нового чата.

Цепочка для нашего эксперимента с подписью выглядит так: браузер открывает http://127.0.0.1:5173 -> Vite отдаёт интерфейс и принимает относительные запросы API и WebSocket -> прокси Vite пересылает их на backend http://127.0.0.1:8080. Обращения к серверу моделей вроде Ollama на http://127.0.0.1:11434 идут отдельно, от Python-процесса backend; получение списка моделей и генерация ответа относятся к этой отдельной цепочке. Сама видимая метка · dev формируется в шаблоне интерфейса, поэтому скачивать и запускать чатовую модель ради проверки этой правки не нужно.

Прежде чем клонировать репозиторий и запускать команды, подготовим изолированную папку и проверим инструменты, чтобы эксперимент не затронул вашу основную установку.

Подготовьте отдельную лабораторию и проверьте инструменты

На каком компьютере повторять эти шаги и как устроить каталоги, чтобы не повредить уже существующие базы и ключи? Мы выбираем один фиксированный маршрут: нативная Ubuntu 24.04 x86_64, обычная учётная запись пользователя без sudo для пакетных менеджеров и оболочка Bash.

Для этого маршрута в системе заранее должны быть установлены Git, Node.js серии 22.x (не ниже 22.10), npm 10, Python 3.11 вместе с модулями venv и pip, а также утилиты curl и ss. Такой выбор опирается на пересечение требований в руководстве по разработке, ограничений requires-python в pyproject.toml, поля engines в package.json и зависимостей в package-lock.json. Хотя первичная документация допускает и Python 3.12, ниже мы используем только команды для python3.11; не подставляйте сюда несовместимые новые выпуски вроде Python 3.13 или Node.js 24.

Все файлы мы разместим внутри нового лабораторного каталога $HOME/open-webui-source-lab, разделив его на независимые части:

  • $HOME/open-webui-source-lab/source — дерево исходного кода (checkout репозитория);
  • $HOME/open-webui-source-lab/venv — виртуальное окружение с установленными Python-пакетами;
  • $HOME/open-webui-source-lab/data — каталог данных DATA_DIR для базы SQLite и локального состояния именно этого экземпляра;
  • $HOME/open-webui-source-lab/webui-secret-key — постоянный файл ключа подписи сессий, лежащий рядом с папками, но вне дерева исходников.

Такое разделение защищает от частой путаницы. Согласно документации стандартного модуля venv, виртуальное окружение изолирует только интерпретатор и установленные библиотеки Python, но не создаёт контейнер, не ограничивает сетевой доступ процесса и не отделяет данные приложения. В то же время код backend/open_webui/env.py и скрипт backend/start.sh по умолчанию ищут данные и файл ключа относительно рабочего каталога backend, а при первом запуске могут применить миграции базы данных. Если подключить разработку к рабочей папке данных или скопировать чужой .env, можно испортить существующую базу. Поэтому мы создаём новую лабораторию, не копируем в неё рабочие базы, ключи или шаблон .env.example (где разрешены широкие настройки CORS_ALLOW_ORIGIN=* и FORWARDED_ALLOW_IPS=*) и никогда не выводим содержимое секретного ключа в терминал.

В качестве кода мы закрепляем выпуск v0.12.3 (опубликован 16 октября 2026 года, проверен по источникам 19 октября 2026 года), которому соответствует точный коммит 91ea4e3421d1d8069f13d4a463fcb5986d94ea60. Это фиксированный учебный снимок релизного кода, выбранный для того, чтобы пути к файлам и номера строк совпадали до символа. Текущая совместная разработка в официальном репозитории ведётся в ветке dev.

Откройте терминал подготовки и проверьте версии инструментов, а также отсутствие активных слушателей на портах 5173 и 8080:

git --version
node --version
npm --version
python3.11 --version
ss -ltn '( sport = :5173 or sport = :8080 )'

Сравните вывод первых четырёх команд с выбранными версиями: Node.js должен принадлежать ветке v22.x (не ниже 22.10.0), npm — версии 10.x, а python3.11 должен откликаться без ошибки. Вывод ss показывает сокеты в состоянии прослушивания (LISTEN) и должен остаться без строк на портах :5173 и :8080. Если нужная версия инструмента отсутствует или хотя бы один из портов уже занят, остановитесь на этом шаге: выясните, какой процесс занимает порт, и не завершайте наугад чужие службы.

Когда условия совпали и оба порта свободны, можно один раз создать каталог лаборатории, получить исходники и установить зависимости.

Получите закреплённые исходники и установите зависимости

Как скачать именно проверенную ревизию кода и почему установка зависимостей по зафиксированным спискам всё равно может обращаться к внешним серверам и выполнять код? Разобьём подготовку на два последовательных блока в терминале. В каждом блоке команда set -e немедленно останавливает выполнение, если любой шаг завершится с ошибкой.

Выполните первый блок однократно в отдельной сессии Bash, чтобы создать структуру каталогов и клонировать выпуск v0.12.3:

set -e
DEV_LAB="$HOME/open-webui-source-lab"
umask 077
test ! -e "$DEV_LAB"
mkdir -m 700 "$DEV_LAB"
mkdir -m 700 "$DEV_LAB/data"
git clone --branch v0.12.3 --depth 1 https://github.com/open-webui/open-webui.git "$DEV_LAB/source"
cd "$DEV_LAB/source"
test "$(git rev-parse HEAD)" = '91ea4e3421d1d8069f13d4a463fcb5986d94ea60'
test ! -e .env

Разберём защитные проверки этого шага:

  • umask 077 и mkdir -m 700 ограничивают доступ к создаваемым папкам лаборатории и будущим файлам только текущим пользователем.
  • test ! -e "$DEV_LAB" проверяет, что пути $HOME/open-webui-source-lab ещё не существует. Если каталог уже есть, скрипт сразу остановится: не очищайте старую папку автоматически и не клонируйте код поверх прежних данных.
  • Клонирование по тегу --branch v0.12.3 --depth 1 переводит репозиторий в состояние detached HEAD — это нормально и ожидаемо для закреплённого снимка выпуска. Не выполняйте здесь git pull и не переключайтесь на плавающую ветку.
  • Проверка git rev-parse HEAD гарантирует, что вы получили ровно коммит 91ea4e3421d1d8069f13d4a463fcb5986d94ea60, а test ! -e .env подтверждает, что в корне репозитория нет файла .env. Сюда не нужно копировать .env, .env.local или .env.development из других проектов.

Теперь в сессии Bash выполните второй блок — установку JavaScript- и Python-зависимостей из корня полученного дерева $DEV_LAB/source:

set -e
DEV_LAB="$HOME/open-webui-source-lab"
cd "$DEV_LAB/source"
test ! -e .env
npm ci
python3.11 -m venv "$DEV_LAB/venv"
"$DEV_LAB/venv/bin/python" -m pip install -r backend/requirements.txt

Как объясняет документация npm ci, эта команда устанавливает пакеты строго по существующему package-lock.json, не перезаписывает lock-файл и завершается ошибкой при расхождении с package.json. Однако npm ci — это не просто пассивная распаковка архивов: установка выполняется с правами вашего пользователя и может запускать lifecycle-скрипты пакетов (в lock-файле этого выпуска флаг hasInstallScript отмечен, например, у cypress, esbuild, onnxruntime-node, sharp, core-js, protobufjs) и догружать платформенные бинарные файлы. Со стороны Python файл backend/requirements.txt фиксирует прямые зависимости, но не закрепляет хеши всех транзитивных пакетов и бинарных wheel-архивов под конкретную систему.

Поэтому фиксация коммита не делает установку полностью автономной или побайтово воспроизводимой. Если npm ci или pip install завершились ошибкой, остановитесь и разберите сообщение: не запускайте sudo npm, не добавляйте --force и не редактируйте package-lock.json или requirements.txt ради обхода сбоя.

Наш короткий маршрут отличается от официального руководства по разработке: там перед первым запуском npm run dev предлагается выполнить полную сборку npm run build. В закреплённом коде backend/open_webui/main.py предусмотрена работа серверной части в режиме API без каталога собранного статического интерфейса build, а сам редактируемый интерфейс в режиме разработки отдаёт Vite. Поэтому здесь шаг npm run build мы пропускаем как ограниченную адаптацию для минимального UI-эксперимента.

Код и библиотеки подготовлены. Теперь первым запустим серверный процесс backend, чтобы он инициализировал пустую базу данных, создал постоянный ключ и подготовил API для будущего интерфейса.

Запустите backend в терминале A

Как запустить серверную часть так, чтобы она слушала только локальный интерфейс 127.0.0.1, сохраняла данные и ключ на своих местах и не унаследовала случайные переменные из вашего рабочего окружения?

В официальном руководстве для этого упоминается короткий скрипт backend/dev.sh. Но если заглянуть в его исходный код для выпуска v0.12.3, обнаружатся две проблемы: во-первых, он запускает uvicorn с жёстко заданным адресом --host 0.0.0.0 (открывая порт всем сетевым интерфейсам машины), а во-вторых, не создаёт файл секретного ключа. Между тем в backend/open_webui/env.py аутентификация WEBUI_AUTH по умолчанию включена (True), а пустой ключ WEBUI_SECRET_KEY вызывает немедленную ошибку при старте. Отключать аутентификацию ради обхода этой проверки нельзя.

Вместо этого мы используем штатный скрипт backend/start.sh и передадим ему аргумент --reload. Этот скрипт учитывает переменные HOST, PORT и WEBUI_SECRET_KEY_FILE: перед запуском сервера он проверяет наличие файла ключа, создаёт его при первом старте и экспортирует значение в процесс, не печатая сам секрет в консоль. Когда в start.sh передаётся аргумент --reload, он подставляется в вызов uvicorn вместо стандартного набора аргументов с количеством воркеров (--workers), поэтому сервер запускается в режиме разработки с отслеживанием изменений Python-кода.

Откройте отдельный терминал A, выполните следующий блок и оставьте процесс работать:

set -e
DEV_LAB="$HOME/open-webui-source-lab"
cd "$DEV_LAB/source/backend"
test ! -e ../.env
test -d "$DEV_LAB/data"
umask 077
env -i HOME="$HOME" PATH="$DEV_LAB/venv/bin:$PATH" LANG="${LANG:-C.UTF-8}" \
  ENV=dev HOST=127.0.0.1 PORT=8080 WEBUI_AUTH=True \
  DATA_DIR="$DEV_LAB/data" \
  WEBUI_SECRET_KEY_FILE="$DEV_LAB/webui-secret-key" \
  CORS_ALLOW_ORIGIN='http://127.0.0.1:5173;http://127.0.0.1:8080' \
  FORWARDED_ALLOW_IPS=127.0.0.1 \
  bash start.sh --reload

Параметры команды:

  • env -i запускает процесс в очищенном окружении, сохраняя только HOME, PATH (где папка $DEV_LAB/venv/bin поставлена первой) и локаль LANG. Это гарантирует, что в лабораторный процесс не попадут унаследованные из вашей оболочки переменные DATABASE_URL, WEBUI_SECRET_KEY, настройки Redis или ключи внешних API. Как видно в backend/open_webui/env.py, переменная DATA_DIR управляет путём к SQLite только тогда, когда не задан DATABASE_URL; а загрузка .env через python-dotenv при переданном абсолютном пути BASE_DIR/.env проверяет именно корневой .env репозитория, отсутствие которого мы перед стартом подтверждаем командой test ! -e ../.env. env -i очищает переменные среды, но не изолирует файловую систему пользователя.
  • HOST=127.0.0.1 и PORT=8080 привязывают слушатель Uvicorn к локальному интерфейсу обратной петли (loopback).
  • DATA_DIR="$DEV_LAB/data" и WEBUI_SECRET_KEY_FILE="$DEV_LAB/webui-secret-key" закрепляют внешние пути для базы данных и постоянного ключа. При перезагрузке кода и повторных запусках эти пути должны оставаться неизменными, чтобы сессии и данные не терялись.
  • WEBUI_AUTH=True явно сохраняет штатный режим со входом по учётной записи.
  • CORS_ALLOW_ORIGIN='http://127.0.0.1:5173;http://127.0.0.1:8080' перечисляет источники (Origin), которым браузерная политика CORS разрешает обращаться к API. CORS — это правило для браузера, а не межсетевой экран (firewall), и само по себе оно не заменяет привязку HOST=127.0.0.1.

Не удивляйтесь, если первый запуск в терминале A займёт заметное время и обратится в сеть. По коду backend/open_webui/main.py, routers/retrieval.py и retrieval/utils.py при стандартном старте инициализируется локальная модель эмбеддингов через SentenceTransformer и snapshot_download с Hugging Face. Это вспомогательный механизм поиска по документам, а не языковая модель для чата. Мы намеренно не добавляем в команду искусственные флаги отключения RAG или OpenAI, чтобы не усложнять конфигурацию, но и не считаем появление первых строк лога достаточным доказательством готовности сервера.

Оставьте терминал A открытым: пока он держит запущенный API, мы поднимем во втором окне сервер интерфейса.

Запустите интерфейс в терминале B

Как запустить редактируемый интерфейс так, чтобы сохранились все подготовительные проверки проекта, а сервер разработки Vite слушал только локальный адрес 127.0.0.1:5173 и знал, куда пересылать запросы API?

В package.json скрипт dev устроен в три шага: сначала автоматически срабатывает predev (npm run crypto:verify), затем npm run pyodide:fetch и только после этого запускается vite dev --host. Вызывать бинарный файл vite напрямую в обход npm run dev не стоит по двум причинам:

  1. Вы пропустите штатную подготовку: скрипт scripts/encryption/artifact.mjs сверяет контрольные суммы зафиксированных в репозитории криптографических артефактов (для неизменённого кода это не требует компилятора Rust), а scripts/prepare-pyodide.js подготавливает в static/pyodide ресурсы браузерного окружения Pyodide, при необходимости скачивая пакеты с CDN и метаданные wheel-пакетов из PyPI.
  2. Как видно в vite.config.ts, константа APP_VERSION берётся из переменной process.env.npm_package_version, которую автоматически подставляет именно запуск через npm run.

При этом в стандартном скрипте dev уже записан флаг --host без адреса, который в конфигурации сервера Vite 5 открывает доступ со всех сетевых адресов. Чтобы сузить прослушивание до локальной петли, мы передадим после разделителя -- явные параметры --host 127.0.0.1 --port 5173 --strictPort. В используемой версии CLI vite 5.4.21 (поверх парсера аргументов cac 6.7.14) при повторении опции применяется последнее переданное значение, поэтому завершающий --host 127.0.0.1 ограничивает адрес Vite локальным интерфейсом, а --strictPort запрещает незаметно переключаться на порт 5174, если 5173 занят.

Откройте второй терминал B (не закрывая терминал A), выполните команду запуска интерфейса и оставьте её работать:

set -e
DEV_LAB="$HOME/open-webui-source-lab"
cd "$DEV_LAB/source"
test ! -e .env
env -i HOME="$HOME" PATH="$PATH" LANG="${LANG:-C.UTF-8}" \
  WEBUI_BACKEND_URL=http://127.0.0.1:8080 \
  npm run dev -- --host 127.0.0.1 --port 5173 --strictPort

Переменная WEBUI_BACKEND_URL=http://127.0.0.1:8080 явно задаёт IPv4-адрес для встроенного в vite.config.ts прокси. Когда вы откроете в браузере этой же машины адрес http://127.0.0.1:5173, все обращения интерфейса к путям /api, /ollama, /openai, /oauth и /ws (включая WebSocket-подключения для /api и /ws) пойдут на 127.0.0.1:5173, а Vite перенаправит их процессу из терминала A на http://127.0.0.1:8080.

Если на этапе crypto:verify, загрузки Pyodide или привязки порта 5173 команда в терминале B остановилась с ошибкой, не ослабляйте проверку целостности и не переходите к следующему порту: сначала устраните причину остановки.

Когда оба процесса запущены в терминалах A и B, нужно последовательно проверить их фактические сетевые адреса, готовность API и вход в учётную запись — прежде чем менять код интерфейса.

Проверьте адреса, API и вход

Что именно должно ответить в системе до того, как мы откроем редактор кода и начнём править компонент боковой панели? Сам по себе текст в терминалах A и B ещё не доказывает, что сокеты привязаны к 127.0.0.1, база данных инициализирована, прокси Vite пропускает запросы, а интерфейс пускает вас внутрь.

Откройте третий терминал C (процессы в A и B продолжают работать) и выполните три проверочные команды:

ss -ltnp '( sport = :5173 or sport = :8080 )'
curl -fsS http://127.0.0.1:8080/ready
curl -f -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:5173/api/config

Каждая строка здесь проверяет свой уровень связки:

ПроверкаЧто ожидаем увидетьЧто именно это подтверждает
ss -ltnp '( sport = :5173 or sport = :8080 )'Слушатели привязаны к 127.0.0.1:5173 и 127.0.0.1:8080Оба сервера действительно слушают локальный loopback-адрес, а не 0.0.0.0 или случайный соседний порт
curl -fsS http://127.0.0.1:8080/readyУспешный ответ {"status":true} без ошибки curlСерверная часть в backend/open_webui/main.py завершила инициализацию старта и проверила доступ к базе данных (а также Redis, если бы он использовался), в отличие от поверхностного маршрута /health
curl ... http://127.0.0.1:5173/api/configКод ответа 200Запрос к порту интерфейса 5173 успешно проходит через прокси Vite на backend 8080 и возвращает конфигурацию

Если ss показывает привязку к 0.0.0.0 или отсутствие одного из портов, либо любой из вызовов curl завершается ошибкой, остановитесь на этом шаге и проверьте вывод в терминалах A и B.

Код 200 от /api/config доказывает, что Vite и FastAPI связаны через прокси, но сам по себе ещё не открывает боковую панель в браузере. Чтобы увидеть кнопку нового чата, нужно пройти аутентификацию.

Откройте в браузере http://127.0.0.1:5173 и создайте отдельную лабораторную учётную запись с новым паролем, который не совпадает с вашими рабочими паролями. Согласно логике backend/open_webui/routers/auths.py, первый единственный зарегистрированный пользователь в новой базе автоматически получает роль администратора (admin), после чего свободная регистрация новых пользователей в конфигурации отключается (подробнее устройство первой учётной записи разобрано в уроке про первый вход и настройки доступа). После входа убедитесь, что левая боковая панель (sidebar) открыта и на ней видна кнопка создания нового чата.

Только теперь, когда перед глазами в браузере открыта боковая панель вашего лабораторного экземпляра, у нас есть точное место для наблюдения за правкой кода.

Добавьте метку к подписи и верните исходную строку

Как убедиться, что браузер отображает именно ваш изменённый исходный код, и не задеть при этом логику работы кнопки, переводы или лицензионные элементы?

В дереве исходников за левую боковую панель отвечает файл src/lib/components/layout/Sidebar.svelte (в нашей лаборатории его полный путь — $HOME/open-webui-source-lab/source/src/lib/components/layout/Sidebar.svelte). В зафиксированном коммите 91ea4e3421d1d8069f13d4a463fcb5986d94ea60 на строке 1234 находится блок видимой подписи кнопки нового чата. В оригинале эта строка выглядит так:

<div class=" self-center text-[0.8125rem] leading-5">{$i18n.t('New Chat')}</div>

Выражение {$i18n.t('New Chat')} обращается к системе локализации из src/lib/i18n/index.ts и подставляет надпись на текущем языке интерфейса (например, «Новый чат» или «New Chat»). Мы не будем редактировать JSON-словари переводов, чтобы результат не зависел от выбранного языка и кеша словарей. Не будем трогать и соседний обработчик нажатия newChatHandler, атрибут доступности aria-label, а также название продукта APP_NAME, логотипы или условия брендинга и лицензии, упомянутые в src/lib/constants.ts.

Откройте файл $HOME/open-webui-source-lab/source/src/lib/components/layout/Sidebar.svelte в текстовом редакторе, найдите эту единственную строку 1234 и добавьте после закрывающей фигурной скобки суффикс · dev, чтобы строка приняла точный вид:

<div class=" self-center text-[0.8125rem] leading-5">{$i18n.t('New Chat')} · dev</div>

Сохраните файл и посмотрите на открытую боковую панель в браузере на http://127.0.0.1:5173. Сервер Vite отслеживает изменения файлов .svelte и передаёт обновление через механизм горячей замены модулей (HMR); если браузер не обновил подпись сразу, обновите страницу вручную. Рядом с текстом кнопки нового чата должна появиться метка · dev. Если метка не появилась, проверьте, что боковая панель развёрнута, а вы отредактировали и сохранили именно файл внутри $HOME/open-webui-source-lab/source: подключать языковую модель для поиска причины здесь не нужно, так как модель в отрисовке этого шаблона не участвует.

Убедившись, что метка · dev появилась, сразу выполните обратный шаг: верните в $HOME/open-webui-source-lab/source/src/lib/components/layout/Sidebar.svelte исходную строку без суффикса, снова сохраните файл и проверьте в браузере, что метка · dev исчезла. Для возврата редактируйте только эту строку вручную — не используйте разрушительные команды вроде git reset --hard или git clean.

После того как подпись в браузере вернулась к исходному виду, проверьте в терминале C, что в файле Sidebar.svelte не осталось незамеченных правок:

DEV_LAB="$HOME/open-webui-source-lab"
cd "$DEV_LAB/source"
git diff -- src/lib/components/layout/Sidebar.svelte

Пустой вывод git diff для этого пути подтверждает, что файл точно возвращён к состоянию выпуска v0.12.3. Два противоположных наблюдения в браузере (появление · dev после сохранения и исчезновение после возврата) связывают конкретную строчку исходного кода с живым интерфейсом. Такая проверка подтверждает только цепочку отображения UI-компонента: она не проверяет сборку production-бандла, работу всех разделов приложения или генерацию ответов моделью.

Остановите процессы и сохраните лабораторию

Как аккуратно завершить текущий сеанс разработки, чтобы в следующий раз не проходить клонирование и установку пакетов заново, и какие задачи остаются за рамками нашего UI-эксперимента?

Разделим четыре действия, которые легко смешать при первом знакомстве с разработкой:

  1. Обновление интерфейса (Vite HMR) срабатывает в терминале B, когда вы сохраняете файл фронтенда вроде Sidebar.svelte.
  2. Перезагрузка серверного процесса (--reload) срабатывает в терминале A под управлением Uvicorn, когда меняются файлы Python в backend.
  3. Остановка процессов (Ctrl+C) завершает работу серверов в терминалах A и B, освобождая порты 8080 и 5173.
  4. Повторный запуск сеанса снова поднимает те же два процесса поверх уже существующих папок source, venv, data и файла webui-secret-key.

Ни один из этих механизмов не является промышленным развёртыванием (production deployment), отказоустойчивым кластером или резервной копией. Аналогично, удаление или пересоздание папки venv меняет только набор Python-библиотек и не заменяет резервное копирование базы в data.

Чтобы закончить работу сейчас, перейдите по очереди в терминалы B и A и нажмите Ctrl+C в каждом из них. Оба процесса остановятся, а папка $HOME/open-webui-source-lab/data с вашей лабораторной учётной записью и файл $HOME/open-webui-source-lab/webui-secret-key останутся на диске. Когда вы захотите продолжить эксперименты с этой же копией позже, не повторяйте одноразовый блок создания каталога с test ! -e "$DEV_LAB" и git clone, а также установку зависимостей: достаточно снова запустить блок backend в терминале A и блок frontend в терминале B с теми же путями.

Что остаётся отдельными задачами, если вы решите пойти дальше?

  • Проверка ответа языковой модели. Только если на этой же машине у вас уже запущена локальная служба Ollama и в ней уже скачана нужная модель, вы можете после UI-эксперимента по желанию проверить генерацию ответа по опубликованному уроку про подключение локальной модели через Ollama. Поскольку в нашем маршруте Python-процесс backend работает нативно в самой ОС Ubuntu (а не внутри контейнера Docker), локальный сервер Ollama на той же машине может быть доступен для него по обычному адресу http://127.0.0.1:11434; правила контейнерного доступа с host.docker.internal сюда переносить не нужно. Учтите также особенность backend/open_webui/config.py: после первой записи настроек в базу данных сохранённые в БД адреса подключений имеют приоритет над новыми переменными окружения. Если вы получите ответ модели, это подтвердит отдельную цепочку backend -> Ollama -> модель.
  • Участие в разработке официального проекта (upstream contribution). Наша лаборатория развёрнута на фиксированном релизном теге v0.12.3, тогда как в официальном руководстве по разработке работа над новыми изменениями ведётся в ветке dev. Кроме того, согласно актуальным правилам участия в проекте (contributing.mdx), запросы на включение кода (code pull requests), за исключением правок перевода и локализации (i18n), принимаются только по явному предварительному запросу мейнтейнеров. Поэтому локальный эксперимент в своей лаборатории не означает автоматической отправки PR в основной репозиторий.

Появление и исчезновение метки · dev в Sidebar.svelte при пустом итоговом git diff наглядно связывают конкретную строку исходного кода с тем, что рисует в браузере сервер Vite. При этом готовность API (/ready), работа прокси (/api/config), вход в учётную запись и связь с языковой моделью проверяются как отдельные звенья, а постоянные данные и ключ подписи живут вне дерева исходников и виртуального окружения Python. Завершите процессы в терминалах A и B сочетанием Ctrl+C, сохранив папку $HOME/open-webui-source-lab: для следующего локального изменения вам понадобится повторить только два блока запуска серверов.

Материалы урока

Отметить прохождение

Отметьте урок после того, как получили проверяемый результат из практической части.