Files
serverAppConfigs/docs/Dankclaw/OpenWebUI.md
T
Frank da68b5ce1a fix: basicauth double-prefix render; open-webui off slirp4netns
basicauth (2026-08-22 incident):
- the Caddyfile template carried its own $2a$14$ prefix and deploy.sh
  substituted the full hash (prefix included), rendering an invalid
  double-prefixed hash. Every basicauth vhost rejected every password
  with 401 and Caddy logged nothing.
- template is now a bare REPLACE_WITH_HASH token; tests pin the render
  contract (no prefix in template; rendered line is exactly 'dank <hash>').

open-webui (2026-08-22 incident):
- its slirp4netns helper process died, leaving the container running
  with only 'lo' in its netns: port 3005 accepted TCP and reset every
  request, so chat served empty responses for ~2 days, unlogged.
- move to a pinned bridge network (systemd-open-webui, 10.89.3.0/24,
  gw 10.89.3.1) — no per-container helper to die.
- LLM endpoint reached via the gateway (host.containers.internal is
  slirp-only): OPENAI_API_BASE_URL=http://10.89.3.1:52625.
- add a quadlet healthcheck: /health (app) + non-loopback interface
  (network liveness; the dead-tap state leaves only 'lo').
- deploy script now copies the .network file too.
- docs updated (OpenWebUI History section, Caddy basic-auth contract).
2026-08-22 13:07:43 -07:00

4.8 KiB
Raw Blame History

OpenWebUI

OpenWebUI is a self-hosted chat interface for LLMs. It connects to OpenAI-compatible endpoints (vLLM, llama.cpp, Ollama) and adds RAG, plugins, tool calling, and multi-user support.

Host: Dankclaw — Port: 3005 (host) → 8080 (container) — Boot-persistent: Quadlet — Docs: https://github.com/open-webui/open-webui

Facts

Item Value
Image ghcr.io/open-webui/open-webui:main (CPU build; Dankclaw is CPU-only)
Port 3005 (host) → 8080 (container). Port 3000 is Gitea's HTTP, so it is not usable.
Data volume /home/dank/Containers/open-webui/data → /app/backend/data
Default backend vLLM on Dankclaw :52625 = frank-default-large (via bridge gateway 10.89.3.1:52625)
Network Pinned bridge systemd-open-webui (10.89.3.0/24, gateway 10.89.3.1) — see History
Persistence Quadlet unit open-webui.service; [Install] WantedBy=default.target
Deploy scripts/deploy-open-webui-quadlet.sh dankclaw

The LLM backends

The fleet runs two OpenAI-compatible endpoints. This mapping is the live state (verified 2026-08-19); it is the reverse of the 2026-08-17 note, which is now out of date.

Endpoint Model name Host Capability
:52625 (vLLM) frank-default-large Dankclaw completion
:7770 (llama.cpp FastMTP) frank-default-small Dankserver completion, multimodal

The default connection points at the local vLLM (frank-default-large), so chat stays on-host. To add the other backend, open Admin → Connections in the UI and point an OpenAI connection at http://192.168.0.235:7770/v1 (key none).

Both endpoints are bare-metal systemd services managed by the sibling vllmScripts repository (not this repo). Model swaps, context sizing, and spec tuning happen there. See the vllmScripts knowledge base.

Boot persistence (Quadlet)

The unit lives at dankclaw/open-webui/quadlet/open-webui.container. On the host it installs to ~/.config/containers/systemd/open-webui.container. The generator turns it into open-webui.service. Because the unit sets [Install] WantedBy=default.target and user linger is on, it starts at boot. systemctl --user is-enabled open-webui.service reports generated (the quadlet boot-start state).

Volumes

Container path Host path
/app/backend/data /home/dank/Containers/open-webui/data

The data dir holds the database, RAG indexes, and uploads. The deploy script creates it if missing and preserves it across reruns.

Healthcheck

The quadlet carries a built-in healthcheck (30s interval, 3 retries, 300s start period). It checks two things from inside the container:

  1. App liveness — GET http://127.0.0.1:8080/health returns 200 ({"status":true}).
  2. Network liveness — a non-loopback interface exists in /sys/class/net. The dead-tap zombie state (History) leaves only lo behind, and this is the check that catches it.

podman ps shows the container as unhealthy if either fails. Probe manually at http://dankclaw:3005/health.

Retired instances

  • The compose open-webui service (port 3000) was never run: 3000 is Gitea's HTTP port, so it could not bind.
  • The bare-container open-webui on Dankserver (port 3000) pointed at a dead backend (:9090) and was removed. Its data dir is preserved on Dankserver in case it is needed.
  • The bare-container searxng on Dankserver (port 8081) was removed. SearXNG now runs only on Dankclaw behind Caddy.

Gotchas

  • Use the non-CUDA image on this CPU-only host.
  • The default admin account is created on first login; secure it immediately.
  • If the backend is loading (3–8 minute model load), OpenWebUI shows connection errors until the model is ready.
  • The LLM is reached via the bridge gateway 10.89.3.1, not host.containers.internal (that name is slirp4netns-only and does not resolve on a bridge). To reach the Dankserver backend, use the LAN address 192.168.0.235:7770.

History

  • 2026-08-22 — slirp4netns → pinned bridge. The unit ran on Network=slirp4netns. The slirp4netns helper process died (no OOM, no kill entry, no crash log found), and the container kept running with only lo in its netns: published port 3005 accepted TCP and reset every request, so chat served empty responses for ~2 days. Nothing logged an error. Moving to a kernel bridge removes the per-container helper entirely, and the healthcheck's interface check makes the zombie state visible if it ever returns.

See Also