name: openwebui-layer description: | Open WebUI with auto-configured LLM providers, MCP servers, and Jupyter code execution. MUST be invoked before any work involving: the openwebui candy, Open WebUI configuration, LLM provider auto-detection, or MCP server discovery for Open WebUI.
openwebui -- Open WebUI with auto-configuration
Candy Properties
| Property | Value |
|---|---|
| Dependencies | python, supervisord |
| Volumes | data -> /opt/data |
| Ports | 8080 |
| Aliases | open-webui -> open-webui |
| Services | openwebui (supervisord, autostart) |
| Install files | pixi.toml, task:, openwebui-entrypoint |
Environment Variables
| Variable | Value |
|---|---|
DATA_DIR |
/opt/data |
PORT |
8080 |
DOCKER |
true |
ENABLE_DIRECT_CONNECTIONS |
true |
ENABLE_CODE_EXECUTION |
true |
ENABLE_PERSISTENT_CONFIG |
false |
Optional Environment Variables (env_accept)
| Variable | Description |
|---|---|
OPENROUTER_API_KEY |
API key for OpenRouter (maps to OPENAI_API_KEY with OpenRouter base URL) |
OLLAMA_API_KEY |
API key for Ollama Cloud inference |
OLLAMA_HOST |
Local Ollama server URL (auto-injected by ollama candy env_provide) |
OPENAI_API_KEY |
Direct OpenAI API key |
OPENAI_API_BASE_URL |
OpenAI-compatible API base URL |
WEBUI_AUTH |
Enable authentication (default: true) |
WEBUI_ADMIN_EMAIL |
Admin account email for first-start setup |
CHARLY_MCP_SERVERS |
JSON array of MCP servers (auto-injected by mcp_provide candies) |
MCP Accepts
| Name | Description |
|---|---|
jupyter |
JupyterLab CRDT MCP server for notebook manipulation |
chrome-devtools |
Chrome DevTools MCP server for browser automation |
Secrets (Two-Tier Architecture)
Tier 1: Infrastructure secrets (podman secrets via secret: field)
Auto-generated, stored in credential store (keyring/config-file fallback):
| Secret | Env Fallback | Purpose | Auto-gen path |
|---|---|---|---|
webui-secret-key |
WEBUI_SECRET_KEY |
JWT + encryption key (CRITICAL: losing it breaks all sessions and OAuth tokens) | charly config time, ProvisionPodmanSecrets |
admin-password |
WEBUI_ADMIN_PASSWORD |
Admin account password — declared as secret_require: |
charly bundle add time, ensureCandySecret |
Provisioned as Secret=charly-openwebui-<name>,type=env,target=<ENV> in the quadlet. The entrypoint checks env vars first (from type=env injection), then file mounts at /run/secrets/ as fallback.
First-run admin login: WEBUI_ADMIN_PASSWORD auto-generates as a 32-byte hex random value if not pre-set. To retrieve the auto-generated password and log in for the first time:
charly secrets get charly/secret WEBUI_ADMIN_PASSWORD
Override with a specific password before the first deploy:
charly secrets set charly/secret WEBUI_ADMIN_PASSWORD <password>
charly config openwebui # picks up the override
Tier 2: User API keys (GPG-encrypted .secrets file)
User-provided API keys stored via charly secrets gpg:
charly secrets gpg set OPENROUTER_API_KEY sk-or-xxx
charly config openwebui --env-file .secrets # Decrypts + injects at config time
Auto-Configuration Entrypoint
The openwebui-entrypoint runs on EVERY start (no sentinel — ENABLE_PERSISTENT_CONFIG=false means env vars always override database config):
- Reads secrets from env vars (podman
type=env) or/run/secrets/file mounts - LLM provider detection:
OLLAMA_HOST->OLLAMA_BASE_URL(Ollama server)OPENROUTER_API_KEY->OPENAI_API_KEY+OPENAI_API_BASE_URL=https://openrouter.ai/api/v1OLLAMA_API_KEY->OPENAI_API_KEY+OPENAI_API_BASE_URL=https://api.ollama.com/v1
- MCP server discovery from
CHARLY_MCP_SERVERSJSON -> buildsTOOL_SERVER_CONNECTIONSJSON for Open WebUI - Jupyter detection — if a jupyter MCP server URL is found, sets
CODE_EXECUTION_ENGINE=jupyter - Execs
open-webui serve
TOOL_SERVER_CONNECTIONS Format
The entrypoint translates charly's CHARLY_MCP_SERVERS format into Open WebUI's expected TOOL_SERVER_CONNECTIONS JSON:
[{
"type": "mcp",
"url": "http://charly-jupyter:8888/mcp",
"spec_type": "url", "spec": "", "path": "",
"auth_type": "", "key": "",
"config": {"enable": true},
"info": {"id": "", "name": "jupyter", "description": "MCP: jupyter"}
}]
Key fields: type must be "mcp" (not "openapi"), config.enable must be true.
Key Design Choice: ENABLE_PERSISTENT_CONFIG=false
This is the critical architectural decision. Without it, Open WebUI's database config overrides environment variables after the first admin-panel save. With it disabled, env vars ALWAYS win — so the entrypoint's dynamic configuration (LLM providers, MCP servers, Jupyter) works reliably on every restart. No sentinel-guarded config patching needed (unlike hermes).
Important: No port_relay Needed
Open WebUI binds to 0.0.0.0:8080 by default. The port_relay field is only for services that bind to 127.0.0.1 (like Chrome DevTools on port 9222). Using port_relay with Open WebUI causes a socat/Open WebUI port conflict on eth0.
Build Notes
- pixi.toml uses
[pypi-dependencies](NOT[feature.default.pypi-dependencies]— thedefaultfeature is reserved in pixi) - Open WebUI is installed via
pip install open-webuiin the pixi environment (~500MB+ of dependencies) - First startup takes ~30 seconds (Alembic DB migrations, model loading). supervisord
autorestart=truehandles transient failures.
Usage
# charly.yml
openwebui:
base: fedora
candy:
- agent-forwarding
- openwebui
- dbus
- charly
ports:
- "8080:8080"
Related Candies
/charly-languages:python-- Python runtime dependency/charly-infrastructure:supervisord-- process manager dependency/charly-hermes:hermes-- alternative AI agent with similar MCP/LLM auto-config pattern
Related Commands
/charly-core:charly-config--charly config openwebui --update-allfor service discovery/charly-build:secrets--charly secretsfor Secret Service / GPG credential management/charly-core:service--charly service status openwebuifor runtime management/charly-build:charly-mcp-cmd-- probe the MCP servers openwebui consumes (auto-configured intoTOOL_SERVER_CONNECTIONSfromCHARLY_MCP_SERVERS):charly check live <provider-image> --filter mcpshows what tools openwebui will see and verifies liveness before debugging openwebui itself.
Related Boxes
/charly-openwebui:openwebui-- the deployed box/charly-jupyter:jupyter-- deploy alongside for MCP notebook access and code execution/charly-ollama:ollama-- deploy alongside for local LLM inference/charly-hermes:hermes-- alternative AI frontend (CLI-based agent vs web UI)
When to Use This Skill
MUST be invoked when the task involves the openwebui candy, Open WebUI configuration, LLM provider auto-detection, MCP server discovery for Open WebUI, or the openwebui entrypoint. Invoke this skill BEFORE reading source code or launching Explore agents.
Related
/charly-image:layer— candy authoring reference (charly.ymlschema, task verbs, service declarations)/charly-check:check— declarative testing (check:block,charly check box,charly check live)