# ===================================================================== # Open WebUI - the front end, and the thing that calls the tool server. # # TWO SETTINGS HERE ARE LOAD-BEARING FOR owuitools. Everything else is # ordinary Open WebUI configuration you can change freely. # # ENABLE_FORWARD_USER_INFO_HEADERS # Sends X-OpenWebUI-User-Id and X-OpenWebUI-Chat-Id to the tool # server. Without them the per-user probe budget has nothing to key # on, and the VM sub-agent's live progress view has no chat to post # into - it degrades to "live progress disabled: no usable chat id # was forwarded", which looks like a broken feature. # # AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER # Open WebUI's own clock on a tool call. IT IS NOT UNLIMITED WHEN # UNSET: env.py falls back to AIOHTTP_CLIENT_TIMEOUT, which # defaults to 300. A vm_agent session drives a real machine for # minutes to hours, and was being cut off at five minutes with the # work already finished. # # There are THREE clocks on that call and they must agree: # OWUITOOLS_VM_WAIT_SECONDS (configs/owuitools.env, 7000) # proxy_read_timeout (configs/services/gateway.nginx.conf, # 7200s, on /tools/vm_agent only) # this one (7200) # Keep the app's the smallest, so IT answers rather than a proxy # cutting the connection with no result. # # If you run this through Portainer, enter these in Portainer's own stack # editor. A redeploy regenerates stack.env and discards edits made to the # file on disk. # # The OIDC block at the bottom is entirely optional - delete it and use # the built-in login form. It is included because it is what this project # was developed against. # ===================================================================== # The project name is pinned, and that matters more than it looks. # # Compose derives a project name from the directory the compose file is # in, so running this as `docker compose -f docs/deployment/...` would # create a network called `deployment_default`. The tool server's own # compose joins Open WebUI's network BY NAME, expecting # `openwebui_default` - so without this line, following the install guide # in order fails at the next step with "network declared as external, but # could not be found". # # If you already run Open WebUI under a different project name, set # OWUITOOLS_OWUI_NETWORK in configs/owuitools.env instead of changing # this. name: openwebui services: open-webui: image: ghcr.io/open-webui/open-webui:main container_name: open-webui restart: unless-stopped init: true ports: - "3000:8080" environment: # --- required by owuitools --------------------------------------- ENABLE_FORWARD_USER_INFO_HEADERS: "True" AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER: "7200" # --- ordinary configuration -------------------------------------- TZ: "UTC" OLLAMA_BASE_URL: "http://host.docker.internal:11434" # Generate one: `openssl rand -hex 32`. Changing it logs everyone out. WEBUI_SECRET_KEY: "CHANGE_ME" WEBUI_URL: "https://ai.example.com" ENABLE_PERSISTENT_CONFIG: "true" ENABLE_API_KEYS: "true" ENABLE_EVALUATION_ARENA_MODELS: "False" # --- optional: OIDC through an identity provider ------------------ # Delete this whole block to use the built-in login form instead. # ENABLE_OAUTH_PERSISTENT_CONFIG=false keeps these under the # compose file's control rather than letting the first boot persist # them into the database and then ignore every later change. ENABLE_OAUTH_PERSISTENT_CONFIG: "false" ENABLE_OAUTH_SIGNUP: "true" ENABLE_LOGIN_FORM: "true" OAUTH_MERGE_ACCOUNTS_BY_EMAIL: "true" OAUTH_PROVIDER_NAME: "authentik" OAUTH_CLIENT_ID: ${OAUTH_CLIENT_ID:-} OAUTH_CLIENT_SECRET: ${OAUTH_CLIENT_SECRET:-} OPENID_PROVIDER_URL: "https://auth.example.com/application/o/open-webui/.well-known/openid-configuration" OPENID_REDIRECT_URI: "https://ai.example.com/oauth/oidc/callback" OAUTH_SCOPES: "openid email profile" ENABLE_OAUTH_ID_TOKEN_COOKIE: "false" ENABLE_OAUTH_ROLE_MANAGEMENT: "true" OAUTH_ROLES_CLAIM: "roles" OAUTH_ALLOWED_ROLES: "user,admin" OAUTH_ADMIN_ROLES: "admin" volumes: - /srv/openwebui/data:/app/backend/data extra_hosts: - "host.docker.internal:host-gateway" healthcheck: test: [ "CMD-SHELL", "python -c \"import urllib.request; urllib.request.urlopen('http://127.0.0.1:8080/health', timeout=5)\" || exit 1" ] interval: 30s timeout: 10s retries: 5 start_period: 40s logging: driver: local options: max-size: "10m" max-file: "5"