--- name: open-webui-administration description: "Administer the self-hosted Open WebUI instance at 10.0.0.204 — config via SQLite, ComfyUI image generation, model connections, user management, and service control." version: 1.0.0 author: agent license: MIT platforms: [linux] metadata: hermes: tags: [open-webui, comfyui, image-generation, self-hosted, administration] --- # Open WebUI Administration Administer the self-hosted Open WebUI instance that backs Hermes Agent API servers for phone-based voice chat and image generation. ## Infrastructure | Component | Host | Detail | |-----------|------|--------| | Open WebUI | 10.0.0.204:8080 | systemd service (`open-webui.service`), runs as root | | Binary | `/root/.local/bin/open-webui serve` | Installed under root | | Database | `/root/.open-webui/webui.db` | SQLite — ALL config lives here | | ComfyUI | 10.0.0.202:8188 | systemd service, RTX 4090, models at `/home/n8n/comfy-ui/models/` | | Hermes API | 10.0.0.42:8653 (open1), 8654 (openz) | Backing LLM connections | **Critical:** Open WebUI is a **systemd service, NOT Docker**. The `docker` command does not exist on 10.0.0.204. All administration is via `systemctl` + SQLite. ## Access - **SSH:** `ssh n8n@10.0.0.204` (password: passw0rd) - **Sudo:** `echo passw0rd | sudo -S ` - **Service control:** `sudo systemctl {start,stop,restart,status} open-webui` - **DB access:** `sudo python3 -c "import sqlite3; db = sqlite3.connect('/root/.open-webui/webui.db'); ..."` ## Config via SQLite All settings are in the `config` table with dot-separated keys. Read with: ```python import sqlite3 db = sqlite3.connect("/root/.open-webui/webui.db") row = db.execute("SELECT value FROM config WHERE key = ?", ("key.name",)).fetchone() ``` Write with: ```python db.execute("UPDATE config SET value = ? WHERE key = ?", (new_value, "key.name")) db.commit() ``` **Always backup before editing:** `sudo cp /root/.open-webui/webui.db /root/.open-webui/webui.db.bak-$(date +%Y%m%d_%H%M%S)` **Restart required after config changes:** `sudo systemctl restart open-webui` ## Key Config Sections ### LLM Connections (OpenAI-compatible) ``` openai.enable = true openai.api_keys = ["", "", ...] # JSON array of bearer tokens openai.api_base_urls = ["http://10.0.0.42:8653/v1", ...] # JSON array of endpoints ``` Each Hermes profile gets its own URL + key pair. open1 = port 8653, openz = port 8654. ### Image Generation (ComfyUI) See `references/comfyui-integration.md` for the full config reference, workflow format, and node mapping. Key config keys: - `image_generation.enable` — `"true"` / `"false"` - `image_generation.engine` — `"comfyui"` (or `"openai"`, `"automatic1111"`) - `image_generation.comfyui.base_url` — `"http://10.0.0.202:8188/"` - `image_generation.comfyui.workflow` — JSON string of the API-format workflow - `image_generation.comfyui.nodes` — JSON array of `{"key": "...", "node_ids": "..."}` mappings ### Audio (STT/TTS) ``` audio.stt.engine = "openai" audio.stt.openai.api_base_url = "http://10.0.0.42:9000/v1" audio.tts.engine = "openai" audio.tts.openai.api_base_url = "http://10.0.0.16:8880/v1" audio.tts.model = "kokoro" audio.tts.voice = "af_heart" ``` ### Users & RBAC Users in the `user` table. Groups in the `group` table. Access grants in `access_grant`. ``` ui.enable_signup = false ui.enable_login_form = true ui.default_user_role = "pending" ``` ## Service Control ```bash # Restart after config changes sudo systemctl restart open-webui # Check status systemctl is-active open-webui sudo journalctl -u open-webui -n 50 # Service file systemctl cat open-webui # → /etc/systemd/system/open-webui.service # ExecStart=/root/.local/bin/open-webui serve # EnvironmentFile=-/root/.env # Environment=DATA_DIR=/root/.open-webui ``` ## ComfyUI Update Procedure See `references/comfyui-update.md` for the full step-by-step. Quick summary: 1. `sudo systemctl stop comfyui` (on 10.0.0.202) 2. `git remote set-url origin https://github.com/Comfy-Org/ComfyUI.git` 3. `git fetch --tags origin && git checkout v` 4. `/home/n8n/comfy-env/bin/pip install -r requirements.txt --upgrade` 5. `sudo systemctl start comfyui` 6. Verify: `curl -s http://10.0.0.202:8188/system_stats` ## Image Icon Troubleshooting (v0.10.2+) The 🖼️ image generation icon in the chat input bar is controlled by a **3-way AND gate** in the frontend (`MessageInput.svelte`). All three must be true or the icon is hidden: ``` showImageGenerationButton = selectedModelIds.length === imageGenerationCapableModels.length && // (A) Model capabilities $config?.features?.enable_image_generation && // (B) Backend flag ($_user.role === 'admin' || $_user?.permissions?.features?.image_generation); // (C) User permission ``` ### Gate A — Model Capabilities Each model preset has a `meta.capabilities` object. The frontend checks `image_generation` on the **active model**, not the global default. A model with `image_generation: false` blocks the icon. The `?? true` default means: - Model with **no** `meta.capabilities` → capable for everything (icon shows) - Model with `meta.capabilities = {vision: true}` (no `image_generation` key) → `undefined ?? true` = true → still capable - Model with `meta.capabilities.image_generation = false` → **NOT capable → icon hidden** **Fix:** Set `image_generation: true` on the specific model via DB or Admin → Workspace → Models → edit → Capabilities. ### Gate B — Backend Flag `image_generation.enable` in the DB `config` table. Read by the frontend via authenticated `GET /api/config` → `features.enable_image_generation`. ### Gate C — User Permission Admins always bypass. Non-admins need `features.image_generation: true` in `user.permissions` config. ### Diagnostic Procedure Run these three curls as admin to identify which gate is failing: ```bash TOKEN="" # Gate B curl -s -H "Authorization: Bearer $TOKEN" http://localhost:8080/api/config | python3 -c "import sys,json; print('enable_image_generation =', json.load(sys.stdin)['features'].get('enable_image_generation'))" # Full image config curl -s -H "Authorization: Bearer $TOKEN" http://localhost:8080/api/v1/images/config | python3 -m json.tool # Gate A — per-model capabilities curl -s -H "Authorization: Bearer $TOKEN" http://localhost:8080/api/v1/models | python3 -c "import sys,json; [print(m['id'], '→ caps=', m.get('info',{}).get('meta',{}).get('capabilities')) for m in json.load(sys.stdin)['data']]" ``` ### Frontend Cache The browser caches `/api/config` and `/api/v1/models`. After any config change, users must **sign out and sign back in** (not just refresh) to clear the frontend `$models` store. A hard refresh alone is not sufficient. ## Pitfalls - **Not Docker.** Open WebUI is a systemd service. `docker` does not exist on 10.0.0.204. - **`ENABLE_IMAGE_GENERATION` env var only matters on first run.** Open WebUI has a dual config system, but with `ENABLE_PERSISTENT_CONFIG=true` (default), the DB takes precedence once a row exists. The env var in `/root/.env` is read at startup and seeds the DB on first run — after that, the DB value is authoritative. Restarting the service does NOT re-apply the env var to an existing DB row. To force the env var: set `ENABLE_PERSISTENT_CONFIG=false`, or delete the `image_generation.enable` row from the config table, or set it via the admin API/UI. **Symptom of confusion:** DB config is correct, env var is set, service restarted, but the image icon still doesn't appear — check the model capabilities gate (A) and frontend cache before blaming the env var. - **Config values are JSON-encoded strings.** Boolean `true` is the string `"true"`, not SQLite integer 1. String values like `"comfyui"` are double-quoted inside the value: `'"comfyui"'`. Use parameterized queries (`?`) for complex JSON values to avoid escaping hell. - **Restart required.** Config changes don't take effect until `systemctl restart open-webui`. - **Frontend cache requires sign-out/in.** After config changes, users must sign out and sign back in — the frontend caches model capabilities and config on login. A hard refresh alone is not enough. - **Backup first.** Always `cp webui.db webui.db.bak-` before editing. - **ComfyUI repo moved.** Old remote `comfyanonymous/ComfyUI` → new remote `Comfy-Org/ComfyUI`. Update the git remote before fetching new tags. - **ComfyUI custom nodes may break on major updates.** `numba` and `facenet-pytorch` had version conflicts after the v0.18→v0.27 jump. Non-blocking for core txt2img but may affect specific custom nodes. ## Support Files - `references/comfyui-integration.md` — Full ComfyUI→Open WebUI integration config: keys, workflow format, node mapping, verification - `references/comfyui-update.md` — Step-by-step ComfyUI update procedure with rollback