Replaces the minimal project description with a comprehensive README including a component overview table, quick start instructions, common Ansible operations, and links to detailed documentation. Aligns with Red Panda Approval™ standards.
11 KiB
Open WebUI
Open WebUI is an extensible, self-hosted AI interface that provides a web-based chat experience for interacting with LLMs. This document covers deployment, Casdoor SSO integration, and configuration.
Architecture
Components
| Component | Location | Purpose |
|---|---|---|
| Open WebUI | Native on Oberon | AI chat interface |
| PostgreSQL | Portia | Database with pgvector extension |
| Casdoor | Titania | SSO identity provider |
| HAProxy | Ariel | TLS termination, routing |
Network Diagram
┌────────────────────────────────────────────────────────────────────┐
│ External Access │
│ https://openwebui.ouranos.helu.ca │
└───────────────────────────────┬────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────────────┐
│ ariel.incus (HAProxy) │
│ TLS termination → proxy to oberon.incus:25588 │
└───────────────────────────────┬────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────────────┐
│ oberon.incus │
│ │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ Open WebUI (systemd) │ │
│ │ - Python 3.12 virtual environment │ │
│ │ - Port 25588 │ │
│ │ - OAuth/OIDC via Casdoor │ │
│ └────────────────────────────────────────────────────────────────┘ │
│ │ │ │
│ │ PostgreSQL │ OIDC │
│ ▼ ▼ │
│ portia.incus:5432 titania.incus:22081 │
│ (openwebui database) (Casdoor SSO) │
└────────────────────────────────────────────────────────────────────┘
Network Ports
| Port | Service | Access |
|---|---|---|
| 25588 | Open WebUI HTTP | Via HAProxy |
| 5432 | PostgreSQL | Internal (Portia) |
| 22081 | Casdoor | Internal (Titania) |
Casdoor SSO Integration
Open WebUI uses native OAuth/OIDC to authenticate against Casdoor. Local signup is disabled—all users must authenticate through Casdoor.
How It Works
- User visits
https://openwebui.ouranos.helu.ca - Open WebUI redirects to Casdoor login page
- User authenticates with Casdoor credentials
- Casdoor redirects back with authorization code
- Open WebUI exchanges code for tokens and creates/updates user session
- User email from Casdoor becomes their Open WebUI identity
Configuration
OAuth settings are defined in host variables and rendered into the environment file:
Host Variables (inventory/host_vars/oberon.incus.yml):
# OAuth/OIDC Configuration (Casdoor SSO)
openwebui_oauth_client_id: "{{ vault_openwebui_oauth_client_id }}"
openwebui_oauth_client_secret: "{{ vault_openwebui_oauth_client_secret }}"
openwebui_oauth_provider_name: "Casdoor"
openwebui_oauth_provider_url: "https://id.ouranos.helu.ca/.well-known/openid-configuration"
# Disable local authentication
openwebui_enable_signup: false
openwebui_enable_email_login: false
Environment Variables (rendered from openwebui.env.j2):
ENABLE_SIGNUP=false
ENABLE_EMAIL_LOGIN=false
ENABLE_OAUTH_SIGNUP=true
OAUTH_CLIENT_ID=<client-id>
OAUTH_CLIENT_SECRET=<client-secret>
OAUTH_PROVIDER_NAME=Casdoor
OPENID_PROVIDER_URL=https://id.ouranos.helu.ca/.well-known/openid-configuration
Casdoor Application
The app-openwebui application is defined in ansible/casdoor/init_data.json.j2:
| Setting | Value |
|---|---|
| Name | app-openwebui |
| Display Name | Open WebUI |
| Redirect URI | https://openwebui.ouranos.helu.ca/oauth/oidc/callback |
| Grant Types | authorization_code, refresh_token |
| Token Format | JWT |
| Token Expiry | 168 hours (7 days) |
Prerequisites
1. PostgreSQL Database
The openwebui database must exist on Portia with the pgvector extension:
ansible-playbook postgresql/deploy.yml
2. Casdoor SSO
Casdoor must be deployed and the app-openwebui application configured:
ansible-playbook casdoor/deploy.yml
3. Vault Secrets
Add to ansible/inventory/group_vars/all/vault.yml:
# OpenWebUI
vault_openwebui_secret_key: "<random-secret>"
vault_openwebui_db_password: "<database-password>"
vault_openwebui_oauth_client_id: "<from-casdoor>"
vault_openwebui_oauth_client_secret: "<from-casdoor>"
# API Keys (optional)
vault_openwebui_openai_api_key: "<openai-key>"
vault_openwebui_anthropic_api_key: "<anthropic-key>"
vault_openwebui_groq_api_key: "<groq-key>"
vault_openwebui_mistral_api_key: "<mistral-key>"
Generate secrets:
# Secret key
openssl rand -hex 32
# Database password
openssl rand -base64 24
Deployment
Fresh Installation
cd ansible
# 1. Ensure PostgreSQL is deployed
ansible-playbook postgresql/deploy.yml
# 2. Deploy Casdoor (if not already deployed)
ansible-playbook casdoor/deploy.yml
# 3. Get OAuth credentials from Casdoor admin UI
# - Navigate to https://id.ouranos.helu.ca
# - Go to Applications → app-openwebui
# - Copy Client ID and Client Secret
# - Update vault.yml with these values
# 4. Deploy Open WebUI
ansible-playbook openwebui/deploy.yml
Verify Deployment
# Check service status
ssh oberon.incus "sudo systemctl status openwebui"
# View logs
ssh oberon.incus "sudo journalctl -u openwebui -f"
# Test health endpoint
curl -s http://oberon.incus:25588/health
# Test via HAProxy
curl -s https://openwebui.ouranos.helu.ca/health
Redeployment
To redeploy Open WebUI (preserves database):
ansible-playbook openwebui/deploy.yml
Configuration Reference
Host Variables
Located in ansible/inventory/host_vars/oberon.incus.yml:
# Service account
openwebui_user: openwebui
openwebui_group: openwebui
openwebui_directory: /srv/openwebui
openwebui_port: 25588
openwebui_host: puck.incus
# Database
openwebui_db_host: portia.incus
openwebui_db_port: 5432
openwebui_db_name: openwebui
openwebui_db_user: openwebui
openwebui_db_password: "{{ vault_openwebui_db_password }}"
# Authentication (SSO only)
openwebui_enable_signup: false
openwebui_enable_email_login: false
# OAuth/OIDC (Casdoor)
openwebui_oauth_client_id: "{{ vault_openwebui_oauth_client_id }}"
openwebui_oauth_client_secret: "{{ vault_openwebui_oauth_client_secret }}"
openwebui_oauth_provider_name: "Casdoor"
openwebui_oauth_provider_url: "https://id.ouranos.helu.ca/.well-known/openid-configuration"
# API Keys
openwebui_openai_api_key: "{{ vault_openwebui_openai_api_key }}"
openwebui_anthropic_api_key: "{{ vault_openwebui_anthropic_api_key }}"
openwebui_groq_api_key: "{{ vault_openwebui_groq_api_key }}"
openwebui_mistral_api_key: "{{ vault_openwebui_mistral_api_key }}"
Data Persistence
Open WebUI data locations:
/srv/openwebui/
├── .venv/ # Python virtual environment
├── .env # Environment configuration
└── data/ # User uploads, cache
Database (on Portia):
PostgreSQL: openwebui database with pgvector extension
User Management
First-Time Setup
After deployment, the first user to authenticate via Casdoor becomes an admin. Subsequent users get standard user roles.
Promoting Users to Admin
- Log in as an existing admin
- Navigate to Admin Panel → Users
- Select the user and change their role to Admin
Existing Users Migration
If users were created before SSO was enabled:
- Users with matching email addresses will be linked automatically
- Users without matching emails must be recreated through Casdoor
Troubleshooting
Service Issues
# Check service status
ssh oberon.incus "sudo systemctl status openwebui"
# View logs
ssh oberon.incus "sudo journalctl -u openwebui -n 100"
# Restart service
ssh oberon.incus "sudo systemctl restart openwebui"
OAuth/OIDC Issues
# Verify Casdoor is accessible
curl -s https://id.ouranos.helu.ca/.well-known/openid-configuration | jq
# Check redirect URI matches
# Must be: https://openwebui.ouranos.helu.ca/oauth/oidc/callback
# Verify client credentials in environment
ssh oberon.incus "sudo grep OAUTH /srv/openwebui/.env"
Database Issues
# Test database connection
ssh oberon.incus "PGPASSWORD=<password> psql -h portia.incus -U openwebui -d openwebui -c '\dt'"
# Check pgvector extension
ssh portia.incus "sudo -u postgres psql -d openwebui -c '\dx'"
Common Errors
| Error | Cause | Solution |
|---|---|---|
| "Invalid redirect_uri" | Mismatch between Casdoor config and Open WebUI | Verify redirect URI in Casdoor matches exactly |
| "Invalid client credentials" | Wrong client ID/secret | Update vault with correct values from Casdoor |
| "OIDC discovery failed" | Casdoor unreachable | Check Casdoor is running on Titania |
| "Database connection failed" | PostgreSQL unreachable | Verify PostgreSQL on Portia, check network |
Security Considerations
- SSO-only authentication - Local signup disabled, all users authenticate through Casdoor
- API keys in vault - All API keys stored encrypted in Ansible vault
- Database credentials - Stored in vault, rendered to environment file with restrictive permissions (0600)
- Session security - JWT tokens with 7-day expiry, managed by Casdoor
Related Documentation
- Casdoor SSO - Identity provider configuration
- PostgreSQL - Database deployment
- HAProxy - TLS termination and routing