Open WebUI
Deploy Open WebUI on Kubernetes with Ollama or OpenAI-compatible model providers, persistent RAG data, optional PostgreSQL and Redis, and scheduled PostgreSQL backups.
Safe Open WebUI horizontal scaling requires PostgreSQL, Redis, shared or object-backed file storage, coordinated migrations, and runtime tuning. The chart does not expose a replica count until it can orchestrate that complete contract. It uses a Recreate upgrade strategy to protect SQLite and database migrations.
Key Features
- SQLite or PostgreSQL — a zero-configuration evaluation path and a production database path
- Bundled or external services — HelmForge PostgreSQL and Redis dependencies or operator-managed endpoints
- Secret-backed connections — application, provider, database, Redis, and S3 credentials
- Database-aware readiness —
/health/dbremoves a pod from endpoints when its database is unavailable - Safe upgrades —
Recreateprevents concurrent migrations and SQLite writers - Network isolation — tokenless ServiceAccount, seccomp, dropped capabilities, and inbound NetworkPolicy
- PostgreSQL backup — scheduled
pg_dumparchives to S3-compatible storage
Installation
HTTPS repository:
helm repo add helmforge https://repo.helmforge.dev
helm repo update
helm install open-webui helmforge/open-webui \
--namespace open-webui \
--create-namespace
OCI registry:
helm install open-webui oci://ghcr.io/helmforgedev/helm/open-webui \
--namespace open-webui \
--create-namespace
The first start can take several minutes while Open WebUI downloads its RAG embedding model. The startup probe intentionally allows approximately ten minutes.
Deployment Examples
openWebui:
ollamaBaseUrl: http://ollama.ollama.svc.cluster.local:11434
existingSecret: open-webui-session
existingSecretKey: secret-key
persistence:
enabled: true
size: 20Gi
ingress:
enabled: true
ingressClassName: nginx
hosts:
- host: chat.example.com
paths:
- path: /
pathType: PrefixSQLite is suitable only for a small single-instance deployment on directly attached local storage. Do not place the SQLite data file on NFS, SMB, CephFS, Azure Files, or another network filesystem.
openWebui:
openaiBaseUrl: https://api.openai.com/v1
openaiExistingSecret: openai-credentials
openaiExistingSecretKey: openai-api-key
existingSecret: open-webui-session
existingSecretKey: secret-key
postgresql:
enabled: true
auth:
database: openwebui
username: openwebui
existingSecret: open-webui-postgresql
redis:
enabled: true
auth:
enabled: true
existingSecret: open-webui-redis
master:
persistence:
enabled: false
persistence:
enabled: true
size: 20GiThe chart targets the Redis client Service and reads redis-password from the
dependency Secret. Both Redis URL variables required for WebSocket coordination
are configured.
database:
mode: external
existingSecret: open-webui-database-url
existingSecretKey: database-url
redisConfig:
mode: external
existingSecret: open-webui-redis-url
existingSecretKey: redis-url
postgresql:
enabled: false
redis:
enabled: falseThe database Secret value is a complete PostgreSQL URL. The Redis Secret value is a complete Redis URL. Inline URLs are accepted for evaluation but are copied into generated Kubernetes Secrets rather than exposed in the Deployment.
postgresql:
enabled: true
backup:
enabled: true
schedule: '0 3 * * *'
s3:
endpoint: https://s3.example.com
bucket: open-webui-backups
prefix: production
existingSecret: open-webui-s3
existingSecretAccessKeyKey: access-key
existingSecretSecretKeyKey: secret-keyUploaded files and cached embedding assets under /app/backend/data are not part of pg_dump. Protect the data PVC
separately when those files are required for recovery, and verify restores on a schedule.
Database Selection
| Mode | Values | Intended use |
|---|---|---|
| SQLite | database.mode: auto, PostgreSQL disabled |
Evaluation on local storage |
| Bundled PostgreSQL | postgresql.enabled: true |
Production starting point |
| External PostgreSQL | database.mode: external |
Operator-managed database |
Conflicting modes fail during Helm rendering. External mode requires either
database.url or database.existingSecret.
Redis and WebSockets
Redis is optional in the supported single-replica architecture. When enabled,
the chart sets REDIS_URL, WEBSOCKET_REDIS_URL,
WEBSOCKET_MANAGER=redis, and ENABLE_WEBSOCKET_SUPPORT=true.
redisConfig.mode=external requires either redisConfig.url or an existing
Secret. It cannot be combined with the bundled Redis dependency.
Security
The default manifests:
- create a dedicated ServiceAccount without a mounted Kubernetes API token;
- enable
RuntimeDefaultseccomp; - disable privilege escalation and drop all Linux capabilities;
- allow inbound traffic only to the named HTTP port;
- keep integration egress open for operator-selected model and identity endpoints;
- retain the generated session Secret across upgrades.
The official Open WebUI image declares UID 0 and requires writable application and home paths. The chart therefore
does not enable runAsNonRoot or a read-only root filesystem by default. Validate a compatible derived image before
overriding those contexts.
For production, use existing Secrets, TLS ingress, a private initial administrator enrollment path, scoped egress rules, and storage encryption.
Backup with External PostgreSQL
The application Secret contains a complete database URL, while pg_dump needs
individual connection fields. Configure the external backup contract separately:
backup:
enabled: true
database:
host: postgres.example.com
port: 5432
name: openwebui
username: openwebui
existingSecret: open-webui-database-password
existingSecretKey: database-password
s3:
endpoint: https://s3.example.com
bucket: open-webui-backups
existingSecret: open-webui-s3
Configuration Reference
Application
| Parameter | Type | Default | Description |
|---|---|---|---|
openWebui.port |
integer | 8080 |
Application listener, container port, and probe target |
openWebui.secretKey |
string | "" |
Inline session key stored in a generated Secret |
openWebui.existingSecret |
string | "" |
Existing session-key Secret |
openWebui.existingSecretKey |
string | secret-key |
Session-key field |
openWebui.ollamaBaseUrl |
string | "" |
Ollama endpoint |
openWebui.openaiBaseUrl |
string | "" |
OpenAI-compatible endpoint |
openWebui.openaiApiKey |
string | "" |
Inline provider key stored in a generated Secret |
openWebui.openaiExistingSecret |
string | "" |
Existing provider-key Secret |
openWebui.doNotTrack |
boolean | true |
Disable supported telemetry |
Datastores
| Parameter | Type | Default | Description |
|---|---|---|---|
database.mode |
string | auto |
auto, sqlite, or external |
database.url |
string | "" |
External PostgreSQL URL |
database.existingSecret |
string | "" |
Existing URL Secret |
redisConfig.mode |
string | auto |
auto, external, or disabled |
redisConfig.url |
string | "" |
External Redis URL |
redisConfig.existingSecret |
string | "" |
Existing Redis URL Secret |
postgresql.enabled |
boolean | false |
Enable bundled PostgreSQL |
redis.enabled |
boolean | false |
Enable bundled Redis |
Exposure and persistence
| Parameter | Type | Default | Description |
|---|---|---|---|
service.type |
string | ClusterIP |
Service exposure |
service.port |
integer | 80 |
Service port, independent of the application listener |
ingress.enabled |
boolean | false |
Create an Ingress |
ingress.hosts |
array | [] |
Required when ingress is enabled |
persistence.enabled |
boolean | true |
Persist /app/backend/data |
persistence.size |
string | 10Gi |
Data PVC request |
networkPolicy.enabled |
boolean | true |
Isolate inbound traffic |
Health and backup
| Parameter | Type | Default | Description |
|---|---|---|---|
probes.startup.path |
string | /health |
Cold-start health endpoint |
probes.liveness.path |
string | /health |
Process health endpoint |
probes.readiness.path |
string | /health/db |
Database-aware readiness endpoint |
backup.enabled |
boolean | false |
Enable PostgreSQL backup |
backup.schedule |
string | 0 3 * * * |
Backup schedule |
backup.s3.endpoint |
string | "" |
S3-compatible endpoint |
backup.s3.bucket |
string | "" |
Backup bucket |
Operations
Verify Service endpoints, application health, and the database-aware readiness route after installation:
kubectl get pods,service,pvc --namespace open-webui
kubectl get endpointslice --namespace open-webui
kubectl logs --namespace open-webui deployment/open-webui-open-webui --tail=100
Before upgrades, back up the database and data PVC. Expect brief downtime from
the Recreate strategy. Do not run mixed Open WebUI versions against one
database.