Skip to content

openwebui-layer

Recipe card from the charly-openwebui plugin (Images — the deployable catalog).

openwebui – Open WebUI with auto-configuration

Section titled “openwebui – Open WebUI with auto-configuration”
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
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)

Section titled “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)
Name Description
jupyter JupyterLab CRDT MCP server for notebook manipulation
chrome-devtools Chrome DevTools MCP server for browser automation

Tier 1: Infrastructure secrets (podman secrets via secret: field)

Section titled “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:

Terminal window
charly secrets get charly/secret WEBUI_ADMIN_PASSWORD

Override with a specific password before the first deploy:

Terminal window
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)

Section titled “Tier 2: User API keys (GPG-encrypted .secrets file)”

User-provided API keys stored via charly secrets gpg:

Terminal window
charly secrets gpg set OPENROUTER_API_KEY sk-or-xxx
charly config openwebui --env-file .secrets # Decrypts + injects at config time

The openwebui-entrypoint runs on EVERY start (no sentinel — ENABLE_PERSISTENT_CONFIG=false means env vars always override database config):

  1. Reads secrets from env vars (podman type=env) or /run/secrets/ file mounts
  2. LLM provider detection:
    • OLLAMA_HOST -> OLLAMA_BASE_URL (Ollama server)
    • OPENROUTER_API_KEY -> OPENAI_API_KEY + OPENAI_API_BASE_URL=https://openrouter.ai/api/v1
    • OLLAMA_API_KEY -> OPENAI_API_KEY + OPENAI_API_BASE_URL=https://api.ollama.com/v1
  3. MCP server discovery from CHARLY_MCP_SERVERS JSON -> builds TOOL_SERVER_CONNECTIONS JSON for Open WebUI
  4. Jupyter detection — if a jupyter MCP server URL is found, sets CODE_EXECUTION_ENGINE=jupyter
  5. Execs open-webui serve

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

Section titled “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).

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.

  • pixi.toml uses [pypi-dependencies] (NOT [feature.default.pypi-dependencies] — the default feature is reserved in pixi)
  • Open WebUI is installed via pip install open-webui in the pixi environment (~500MB+ of dependencies)
  • First startup takes ~30 seconds (Alembic DB migrations, model loading). supervisord autorestart=true handles transient failures.
charly.yml
openwebui:
base: fedora
candy:
- agent-forwarding
- openwebui
- dbus
- charly
ports:
- "8080:8080"
  • /charly-core:charly-configcharly config openwebui --update-all for service discovery
  • /charly-build:secretscharly secrets for Secret Service / GPG credential management
  • /charly-core:servicecharly service status openwebui for runtime management
  • /charly-build:charly-mcp-cmd – probe the MCP servers openwebui consumes (auto-configured into TOOL_SERVER_CONNECTIONS from CHARLY_MCP_SERVERS): charly check live <provider-image> --filter mcp shows what tools openwebui will see and verifies liveness before debugging openwebui itself.

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.

  • /charly-image:layer — candy authoring reference (charly.yml schema, task verbs, service declarations)
  • /charly-check:check — declarative testing (check: block, charly check box, charly check live)