Open WebUI Open WebUI

[SSO] User-friendly WebUI for LLMs

Open WebUI is an extensible, feature-rich, and user-friendly self-hosted WebUI for various LLM runners, supported LLM runners include Ollama and OpenAI-compatible APIs.

References

Compose file based on: open-webui/docker-compose.yaml at main ยท open-webui/open-webui

Authentik

Open WebUI uses native OIDC for Authentik’s users group. It redirects to Authentik by default while retaining password authentication for recovery; use ?form=1 on the login page to access the local form.

Setup

Create config/docker/<host>/open-webui/authentik-client-secret with mode 0600. Set OPEN_WEBUI_AUTHENTIK_CLIENT_ID, OPEN_WEBUI_AUTHENTIK_CLIENT_SECRET in ignored config/docker/<host>/.env.open-webui, and set OPEN_WEBUI_AUTHENTIK_SIGNING_KEY in the ignored host .env. The signing key is an asymmetric Authentik certificate/key UUID used for ID-token validation.

scripts/authentik-apps.py --application open-webui --apply
scripts/labctl.py service recreate ai/open-webui

Keep the callback URI exact: https://open-webui.<domain>/oauth/oidc/callback. Account merging by email requires Authentik to provide verified, unique email addresses.

Verify

Confirm an authorized user can sign in, a user outside users is denied, an existing account links as intended, and local-password recovery still works.

Backup

backup.yaml exports both webui.db and Chroma’s SQLite DB online each night under ${DB_BACKUP_ROOT}/ai-open-webui/. B2 must pair them with uploads, vectors, extensions and the pinned MiniLM archive outside the excluded cache. Restore the original WEBUI_SECRET_KEY; model/settings changes require updating the archive pin. See the backup guide for commands, retention and snapshot selection.

Recovery

  1. Stop the destination. Restore database.sqlite3 as /app/backend/data/webui.db and database-chroma.sqlite3 as /app/backend/data/vector_db/chroma.sqlite3; discard stale destination WAL/SHM.
  2. Restore paired uploads, docs, vector index files, functions, tools and litellm state, plus original WEBUI_SECRET_KEY and OIDC settings. Start the matching application image. The SQLite exports and vector files are not an atomic capture, so check known document references after recovery.
  3. For offline embedding, recover the revision referenced by the export’s model metadata from open-webui/offline-models/all-MiniLM-L6-v2/<revision>/ in the application snapshot. Verify model.tar.gz size/hash and contained file hashes against its manifest.json, then extract into a stable local directory; the archive contains a model/ tree, including upstream model/license metadata.
  4. Point RAG_EMBEDDING_MODEL to that local model directory and enable HF_HUB_OFFLINE=1 and TRANSFORMERS_OFFLINE=1. The restored persistent rag.embedding_model setting takes precedence over the environment; update it on the restored instance. ENABLE_PERSISTENT_CONFIG=False was an isolated drill alternative, not a required production recovery setting.

Local model retention preserves three recent revisions plus every revision referenced by retained DB exports, and runs only after B2 coverage passes.

Post-restore check

Restore both standalone SQLite exports and paired files; discard old DB WAL/SHM sidecars before starting. Verify /health, open one historical chat/upload, and run one known document query with a local model. For offline embedding, extract the pinned archive, point the restored embedding setting at its local model/ directory, and enable Hugging Face offline mode. Follow the persistent-setting steps above on the restored instance rather than changing the working instance.

name: open-webui
services:
  open-webui:
    image: openwebui/open-webui:0.12.5@sha256:03443b8de6b617da9d900edd09b4bf1cb0ddbfdcba6afb42c548336a0b821ded
    container_name: open-webui
    restart: unless-stopped
    volumes:
      - ${DOCKER_VOLUMES}/open-webui:/app/backend/data
    networks:
      - proxy
    # Environment Variable Configuration
    # https://docs.openwebui.com/getting-started/advanced-topics/env-configuration/
    environment:
      WEBUI_SECRET_KEY: ${OPEN_WEBUI_SECRET_KEY}
      WEBUI_URL: "https://open-webui.${MYDOMAIN}"

      # Auth
      # Use Authentik by default; append ?form=1 to the login URL for local password recovery.
      ENABLE_LOGIN_FORM: "false"
      ENABLE_PASSWORD_AUTH: "true"
      ENABLE_OAUTH: "true"
      ENABLE_OAUTH_SIGNUP: "true"
      OAUTH_AUTO_REDIRECT: "true"
      OAUTH_MERGE_ACCOUNTS_BY_EMAIL: "true"
      OAUTH_CLIENT_ID: ${OPEN_WEBUI_AUTHENTIK_CLIENT_ID:?Configure Open WebUI Authentik client ID}
      OAUTH_CLIENT_SECRET: ${OPEN_WEBUI_AUTHENTIK_CLIENT_SECRET:?Configure Open WebUI Authentik client secret}
      OPENID_PROVIDER_URL: "https://sso.${MYDOMAIN}/application/o/open-webui/.well-known/openid-configuration"
      OPENID_REDIRECT_URI: "https://open-webui.${MYDOMAIN}/oauth/oidc/callback"
      OAUTH_SCOPES: "openid email profile"
      OLLAMA_API_BASE_URL: "https://ollama.${MYDOMAIN}/api"

      # Web search using SearXNG
      # Details: https://github.com/open-webui/docs/blob/main/docs/tutorials/integrations/web_search.md
      ENABLE_RAG_WEB_SEARCH: true
      RAG_WEB_SEARCH_ENGINE: "searxng"
      RAG_WEB_SEARCH_RESULT_COUNT: 5
      RAG_WEB_SEARCH_CONCURRENT_REQUESTS: 10
      SEARXNG_QUERY_URL: "https://searxng.${MYDOMAIN}/search?q=<query>&format=json"

      # Image models
      # https://github.com/open-webui/docs/blob/main/docs/reference/env-configuration.mdx#image_url_response_models_regex_pattern
      IMAGE_URL_RESPONSE_MODELS_REGEX_PATTERN: "^gpt-image|.*gpt-.*-image"
      # Fixes "Got more than 131072 bytes when reading" for image generation models
      # that stream base64-encoded images as large SSE lines (e.g. gpt-5.4-image-2 via OpenRouter).
      # Switches from aiohttp line-based iteration to iter_chunks(), bypassing the 128KB limit.
      # See: https://github.com/open-webui/open-webui/issues/17626
      CHAT_STREAM_RESPONSE_CHUNK_MAX_BUFFER_SIZE: 20971520
    extra_hosts:
      - host.docker.internal:host-gateway
    labels:
      traefik.enable: true
      traefik.http.routers.open-webui.middlewares: localaccess@file
      traefik.http.services.open-webui.loadbalancer.server.port: 8080
      homepage.group: AI
      homepage.name: "Open WebUI"
      homepage.icon: open-webui.png
      homepage.href: https://open-webui.${MYDOMAIN}/
      homepage.description: "[SSO] User-friendly WebUI for LLMs"

networks:
  proxy:
    external: true