Initial skills documentation — 25 categories, all SKILL.md + references + scripts
This commit is contained in:
@@ -0,0 +1,238 @@
|
||||
---
|
||||
name: open-webui
|
||||
description: Deploy, configure, and upgrade Open WebUI on app1 — vision support, image generation, RAG, model management, and admin-ai backend integration.
|
||||
version: 1.0.0
|
||||
tags: [open-webui, ai, chat, vision, rag, app1, admin-ai, docker]
|
||||
---
|
||||
|
||||
# Open WebUI
|
||||
|
||||
Self-hosted AI chat interface at `http://ai.itpropartner.com` running on app1 (152.53.36.131).
|
||||
|
||||
## Architecture
|
||||
|
||||
```text
|
||||
User → Caddy (ai.itpropartner.com) → localhost:3000 → Open WebUI Docker
|
||||
↓
|
||||
admin-ai.itpropartner.com/v1 (LiteLLM)
|
||||
↓
|
||||
100+ models across providers
|
||||
```
|
||||
|
||||
## Deployment
|
||||
|
||||
```bash
|
||||
# On app1: /docker/openwebui/docker-compose.yml
|
||||
services:
|
||||
openwebui:
|
||||
image: ghcr.io/open-webui/open-webui:latest
|
||||
container_name: openwebui
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "127.0.0.1:3000:8080"
|
||||
environment:
|
||||
- OPENAI_API_BASE_URL=https://admin-ai.itpropartner.com/v1
|
||||
- OPENAI_API_KEY=<admin-ai-key>
|
||||
- WEBUI_NAME=IT Pro Partner AI
|
||||
volumes:
|
||||
- openwebui_data:/app/backend/data
|
||||
volumes:
|
||||
openwebui_data:
|
||||
external: true
|
||||
```
|
||||
|
||||
## Models
|
||||
|
||||
100+ models through admin-ai. Vision-capable: claude-sonnet-4-6, gemini-flash-latest, gemini-pro-latest.
|
||||
|
||||
## Troubleshooting: No Models Showing Up
|
||||
|
||||
When OpenWebUI shows an empty model list, the API connection is failing. The DB values for `openai.api_base_urls` and `openai.api_keys` override docker-compose env vars after they've been set via the Admin UI.
|
||||
|
||||
### Quick diagnostic
|
||||
|
||||
```bash
|
||||
# Test connectivity from inside the container
|
||||
docker exec openwebui curl -s <base_url>/v1/models -H 'Authorization: Bearer <key>' | head -c 200
|
||||
|
||||
# Check current DB config
|
||||
sqlite3 /var/lib/docker/volumes/openwebui_data/_data/webui.db \
|
||||
"SELECT key, substr(value, 1, 120) FROM config WHERE key IN ('openai.api_base_urls', 'openai.api_keys')"
|
||||
```
|
||||
|
||||
### Common misconfigurations
|
||||
|
||||
- **`http://litellm:4000/v1`** — LiteLLM runs on core (netcup), not locally on app1. `litellm` hostname does NOT resolve from app1's Docker network. Use `https://admin-ai.itpropartner.com/v1` instead.
|
||||
- **Wrong/missing API key** — The key stored in `openai.api_keys` must be a valid LiteLLM key with access to `GET /v1/models`.
|
||||
|
||||
### Fix
|
||||
|
||||
```python
|
||||
import sqlite3, json, time
|
||||
db = sqlite3.connect('/var/lib/docker/volumes/openwebui_data/_data/webui.db')
|
||||
|
||||
# Fix base URL
|
||||
db.execute("UPDATE config SET value = ?, updated_at = ? WHERE key = 'openai.api_base_urls'",
|
||||
(json.dumps(['https://admin-ai.itpropartner.com/v1']), int(time.time())))
|
||||
db.commit()
|
||||
db.close()
|
||||
```
|
||||
|
||||
Then restart: `docker restart openwebui`
|
||||
|
||||
## Enabling Vision Support (CRITICAL)
|
||||
|
||||
Open WebUI uses `ConfigVar` environment variables — after first launch, values persist in the SQLite database and env var changes are **ignored**. Must update the DB directly:
|
||||
|
||||
```python
|
||||
import sqlite3, json, time
|
||||
db = sqlite3.connect('/var/lib/docker/volumes/openwebui_data/_data/webui.db')
|
||||
db.execute("""
|
||||
UPDATE config
|
||||
SET value = ?, updated_at = ?
|
||||
WHERE key = 'models.default_metadata'
|
||||
""", ('{"capabilities": {"vision": true}}', int(time.time())))
|
||||
db.commit()
|
||||
db.close()
|
||||
```
|
||||
|
||||
Then restart: `docker restart openwebui`
|
||||
|
||||
**Pitfall:** Setting `DEFAULT_MODEL_METADATA` in docker-compose.yml only works on FIRST launch. Subsequent restarts use the DB value. Always update both — the compose file for fresh deploys AND the DB for live instances.
|
||||
|
||||
## Web Search
|
||||
|
||||
Configured via DB config keys. Open WebUI supports multiple search backends — switch between them by updating `web.search.engine` and the corresponding credentials.
|
||||
|
||||
### Current setup (Google PSE)
|
||||
|
||||
```python
|
||||
import sqlite3, time
|
||||
db = sqlite3.connect('/var/lib/docker/volumes/openwebui_data/_data/webui.db')
|
||||
|
||||
db.execute("UPDATE config SET value = ?, updated_at = ? WHERE key = ?",
|
||||
('true', int(time.time()), 'web.search.enable'))
|
||||
db.execute("UPDATE config SET value = ?, updated_at = ? WHERE key = ?",
|
||||
('"google_pse"', int(time.time()), 'web.search.engine'))
|
||||
db.commit()
|
||||
```
|
||||
|
||||
Google PSE keys are already in the DB:
|
||||
- `web.search.google_pse_api_key`
|
||||
- `web.search.google_pse_engine_id`
|
||||
|
||||
### Switching search engines
|
||||
|
||||
- `"searxng"` — uses `web.search.searxng_query_url` (public instances are rate-limited; deploy your own)
|
||||
- `"google_pse"` — uses Google Programmable Search Engine (pre-configured, works reliably)
|
||||
- Other backends: brave, kagi, serpapi, tavily, etc. — each needs its own API key row
|
||||
|
||||
### Enabling web search in chat
|
||||
|
||||
Users click the 🌐 toggle in the chat input to enable web search per-message. Results are injected as RAG context with inline citations.
|
||||
|
||||
## MCP Connectivity
|
||||
|
||||
Open WebUI natively supports MCP Streamable HTTP connections. Add via **Admin Settings → External Tools** (UI) or directly in the SQLite DB.
|
||||
|
||||
### Adding an MCP server via DB
|
||||
|
||||
```python
|
||||
import sqlite3, json, time
|
||||
db = sqlite3.connect('/var/lib/docker/volumes/openwebui_data/_data/webui.db')
|
||||
|
||||
row = db.execute("SELECT value FROM config WHERE key='tool_server.connections'").fetchone()
|
||||
current = json.loads(row[0]) if row else []
|
||||
|
||||
new_conn = {
|
||||
'url': 'http://host.docker.internal:8899/mcp', # Use host.docker.internal for Docker→host
|
||||
'type': 'mcp', # NOT 'openapi'
|
||||
'auth_type': 'none', # 'none', 'bearer', or 'oauth_2.1'
|
||||
'key': '',
|
||||
'config': {
|
||||
'enable': True,
|
||||
'function_name_filter_list': '', # Leave empty to expose all tools
|
||||
'access_grants': [{'principal_type': 'group', 'principal_id': '<group-id>', 'permission': 'read'}]
|
||||
},
|
||||
'info': {'name': 'My MCP Server', 'description': '...'}
|
||||
}
|
||||
current.append(new_conn)
|
||||
db.execute("UPDATE config SET value = ?, updated_at = ? WHERE key = ?",
|
||||
(json.dumps(current), int(time.time()), 'tool_server.connections'))
|
||||
db.commit()
|
||||
```
|
||||
|
||||
Then restart: `docker restart openwebui`
|
||||
|
||||
### MCP vs OpenAPI connection types
|
||||
|
||||
- **MCP (Streamable HTTP):** Type `"mcp"` — stateful, tool-rich, follows MCP protocol
|
||||
- **OpenAPI:** Type `"openapi"` — stateless REST, follows OpenAPI spec
|
||||
|
||||
**Pitfall:** Using `"openapi"` as the type for an MCP server URL causes an infinite loading spinner and browser console error. Always use `"mcp"` for MCP servers.
|
||||
|
||||
### Access Control
|
||||
|
||||
MCP servers are admin-only to add. Grant user access via `access_grants` — assign to a group so all users in that group get the tools.
|
||||
|
||||
### Docker→host addressing
|
||||
|
||||
When Open WebUI runs in Docker and the MCP server is on the host, use `http://host.docker.internal:<port>/mcp` instead of `localhost`.
|
||||
|
||||
Configured via admin-ai → Gemini Imagen:
|
||||
- Engine: openai (OpenAI-compatible API)
|
||||
- Model: `gemini/imagen-4.0-generate-001`
|
||||
- Size: 2048x2048
|
||||
|
||||
Enabled in DB config: `('image_generation.enable', 'true')`
|
||||
|
||||
## Document Upload (RAG)
|
||||
|
||||
PDFs, files, and documents are processed through the built-in RAG pipeline:
|
||||
- Embedding model: `sentence-transformers/all-MiniLM-L6-v2` (downloaded from HuggingFace on first use)
|
||||
- Vector DB: ChromaDB (SQLite-backed, local)
|
||||
- PDF extraction: page-based mode, PDF image extraction enabled
|
||||
- Chunk size: 1000, overlap: 100
|
||||
|
||||
## DB Config Reference
|
||||
|
||||
Database: `/var/lib/docker/volumes/openwebui_data/_data/webui.db`
|
||||
Schema: `config(key TEXT PRIMARY KEY, value JSON, updated_at BIGINT)`
|
||||
|
||||
Key rows to know about:
|
||||
| key | purpose |
|
||||
|---|---|
|
||||
| `models.default_metadata` | Vision, image_gen capabilities |
|
||||
| `image_generation.enable` | Image gen toggle |
|
||||
| `image_generation.model` | Active image gen model |
|
||||
| `openai.api_base_urls` | Backend API URL |
|
||||
| `openai.api_keys` | Backend API key |
|
||||
| `user.permissions` | Feature flags per role |
|
||||
|
||||
## Restart
|
||||
|
||||
```bash
|
||||
cd /docker/openwebui && docker compose down && docker compose up -d
|
||||
# or for quick restart:
|
||||
docker restart openwebui
|
||||
```
|
||||
|
||||
## Upgrades
|
||||
|
||||
```bash
|
||||
cd /docker/openwebui
|
||||
docker compose pull
|
||||
docker compose down && docker compose up -d
|
||||
# Re-apply vision metadata (config may reset on major upgrades)
|
||||
```
|
||||
|
||||
## Pitfalls
|
||||
|
||||
- **ConfigVar persistence:** After first launch, env vars like `DEFAULT_MODEL_METADATA` are ignored. Always update the SQLite DB directly for running instances. Set both env AND DB for fresh deploys.
|
||||
- **Container name conflict:** `docker compose down` sometimes leaves the container name reserved. Use `docker rm -f openwebui` before `docker compose up`.
|
||||
- **No sqlite3 in container:** Use Python `sqlite3` module on the host, pointing at the Docker volume path.
|
||||
- **Model list refresh:** Models from admin-ai are fetched at startup. If admin-ai models change, restart Open WebUI to refresh.
|
||||
- **MCP type mismatch:** Using `"openapi"` connection type for an MCP server crashes the frontend with an infinite loading spinner. Always use `"mcp"`.
|
||||
- **Web search engine switch:** Google PSE is pre-configured and reliable. Public SearXNG instances are rate-limited — deploy your own if you need SearXNG.
|
||||
- **`http://litellm:4000/v1` won't resolve:** LiteLLM runs on core (netcup), not locally on app1. The `litellm` hostname doesn't resolve from app1's Docker network. Always use `https://admin-ai.itpropartner.com/v1` as the base URL. This is the most common cause of "no models showing up."
|
||||
- **UI overrides env vars in DB:** `openai.api_base_urls` and `openai.api_keys` set via Admin UI persist in the SQLite DB and override docker-compose environment variables. When models disappear, check the DB values first, not the compose file.
|
||||
Reference in New Issue
Block a user