Skip to content

OpenWebUI

hal0 ships OpenWebUI as the chat surface. The installer wires it to the local hal0 API automatically — zero config, open http://localhost:3001 after install.

The dashboard is for operating the box (slots, models, hardware, logs). It isn’t a chat UI. OpenWebUI is a full chat client with conversation history, model switching, RAG, prompt presets, and voice mode, all under a permissive license.

Bundling means:

  • One install command, two UIs ready. No “now go install OpenWebUI separately and figure out the API URL.”
  • Same lifecycle. OpenWebUI is a systemd unit, updates with hal0 update, logs into journald.
  • The env is right by default. OPENAI_API_BASE_URLS points at http://127.0.0.1:8080/v1; OPENAI_API_KEYS is set to a local token.
ComponentLocation
Service unithal0-openwebui.service
Listen port:3001 (binds public interfaces)
State directory/var/lib/hal0/openwebui/
Env file/etc/hal0/openwebui.env

State (chats, prompts, RAG documents) lives under /var/lib/hal0/, so hal0 update preserves your conversation history.

Terminal window
xdg-open http://localhost:3001

On first launch OpenWebUI walks through its own account-creation flow. After that, models from /v1/models populate the model dropdown — both slot aliases and registry refs.

Standard OpenWebUI environment variables work; set them in /etc/hal0/openwebui.env and restart the service:

Terminal window
sudo systemctl restart hal0-openwebui.service

The installer writes this file once at install time; it’s not overwritten on hal0 update.

If your homelab already runs Traefik or Caddy in front of *.lan or *.thinmint.dev services, point it at OpenWebUI directly instead of using hal0’s bundled Caddy. Always give OpenWebUI its own hostname (e.g. hal0-chat.lan, hal0-chat.thinmint.dev) or its own port. OpenWebUI emits root-absolute asset URLs and has no base-path config, so a PathPrefix rule under your dashboard’s hostname will 404 every asset. There is no workaround in OWUI today — this is a hard constraint, not a misconfiguration.

A typical Traefik dynamic config snippet:

http:
routers:
hal0-chat:
rule: "Host(`hal0-chat.lan`)"
service: hal0-chat
entryPoints: [websecure]
tls: {}
services:
hal0-chat:
loadBalancer:
servers:
- url: "http://<hal0-host>:3001"

Do auth at the proxy (forward-auth, OIDC middleware, basic_auth, whatever you already trust). OpenWebUI’s WEBUI_AUTH_TRUSTED_EMAIL_HEADER will pick up the forwarded identity exactly like it does with hal0’s bundled Caddy. If you want OpenWebUI to be reachable only through the proxy and not directly on :3001, firewall the port at the host or front it with the proxy on a different interface.

If you don’t want OpenWebUI:

Terminal window
sudo systemctl disable --now hal0-openwebui.service

The hal0 API keeps running. The dashboard at :8080 keeps running. You can reach the /v1/* endpoints from any other client.

  • Single sign-on between dashboard and OpenWebUI.
  • Shared theme tokens so OpenWebUI inherits the hal0 amber.
  • One-click voice-mode wiring (OpenWebUI → stt slot → primary slot → tts slot).