Files

197 lines
8.7 KiB
Markdown
Raw Permalink Normal View History

---
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 <command>`
- **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 = ["<key1>", "<key2>", ...] # 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<version>`
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="<admin JWT or API key>"
# 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-<timestamp>` 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