AI & LLM Tools

Deploy Open WebUI on Kubernetes with Helm

J
James Eriksson
··10 min read
Deploy Open WebUI on Kubernetes using Helm. Configure storage, Ollama integration, ingress, TLS, and OIDC authentication. Production-ready setup in 30 minutes.
TL;DR
  • The Open WebUI Helm chart deploys a ChatGPT-like UI on Kubernetes with PostgreSQL, Ollama, and OIDC support in one values.yaml file.
  • Persistent storage via PVC keeps conversations safe; use S3 for multi-cluster portability.
  • Enable the Ollama sub-chart to run private LLMs in-cluster; allocate 4GB RAM and 20GB storage per Ollama replica.
  • Configure ingress, TLS with cert-manager, and OIDC for production-grade security and SSO.
  • Safe upgrades use rolling updates; run two or more replicas and Redis for zero-downtime deployments.

The Open WebUI Helm chart puts a ChatGPT-like interface on your Kubernetes cluster in minutes. You control the infrastructure and choose which LLM backends run behind it: local Ollama, cloud APIs, or both. This guide covers deployment, persistent storage configuration, Ollama integration, authentication, and safe upgrades.

Prerequisites for Kubernetes Helm Deployment

Before you start, make sure you have a working Kubernetes cluster and the tools to manage it. You need kubectl installed and configured to access your cluster. You also need Helm 3.x or later.

Decide what backs your data before installing. Open WebUI needs persistent storage for conversations, settings, and user data. You can use a Kubernetes PersistentVolumeClaim (PVC) backed by local storage or a cloud provider's storage class. You can also configure S3-compatible storage for multi-cluster setups. Choose PVC if you have a single cluster and storage redundancy is handled by your infrastructure. Choose S3 if you need the flexibility to move data between clusters or regions.

Plan your PostgreSQL setup. Open WebUI works with SQLite by default, but production deployments should use PostgreSQL. You can run PostgreSQL in the same cluster using Helm, or use a managed service from your cloud provider. Managed PostgreSQL is simpler but costs more. Self-hosted PostgreSQL in-cluster saves money but requires you to back it up and scale it yourself.

Consider Redis for session caching if you're running multiple replicas of Open WebUI. A single replica doesn't need it. Two or more replicas should have Redis, either in-cluster or managed. This ensures sessions persist across pod restarts.

Gather infrastructure info: your cluster's storage classes, whether ingress-nginx is installed, your domain name, and your OIDC provider details if you're using SSO.

Adding the Helm Repository and Installing Open WebUI

Add the Open WebUI Helm chart repository from the official endpoint and update your local cache:

helm repo add open-webui <official-helm-endpoint>
helm repo update
kubectl create namespace open-webui

The simplest install uses default settings:

helm install open-webui open-webui/open-webui -n open-webui

This creates a deployment with one replica, SQLite storage, and no ingress. It works for testing but not for production.

Verify the pod is running:

kubectl get pods -n open-webui

You should see a pod with status "Running" within 30 seconds. Port-forward to test the UI:

kubectl port-forward -n open-webui svc/open-webui 3000:8080

Open http://localhost:3000 in your browser. You should see the Open WebUI login screen.

For real deployments, create a values.yaml file and pass it to helm install:

helm install open-webui open-webui/open-webui -n open-webui -f values.yaml

This separates your configuration from the helm command, making upgrades safer. Keep values.yaml in version control.

Configuring Persistent Storage (PVC vs S3)

Persistent storage keeps your conversations and settings even after pod restarts. By default, Open WebUI uses an emptyDir volume, which deletes data when the pod stops. This is fine for demos. Production needs persistent storage.

Use Kubernetes PersistentVolumeClaims (PVC) for most setups. Add this to values.yaml:

persistence:
  enabled: true
  storageClass: "standard"
  size: 10Gi
  accessModes:
    - ReadWriteOnce

Replace "standard" with your cluster's storage class. Get the list:

kubectl get storageclasses

GCP uses "standard-rwo", AWS uses "gp2" or "gp3", Hetzner uses "local-storage" or "csi-lvm" depending on cluster type. Set size to 10Gi initially. Increase if conversations grow beyond 80% capacity.

Use S3 for multi-cluster or cloud-native deployments. S3 decouples data from the cluster, so you can move Open WebUI to a new cluster without losing history:

persistence:
  enabled: true
  type: s3
  s3:
    endpoint: "s3.amazonaws.com"
    region: "us-east-1"
    bucket: "my-open-webui-bucket"
    accessKey: "YOUR_AWS_KEY"
    secretKey: "YOUR_AWS_SECRET"

For GCS, set the endpoint to "storage.googleapis.com". For Backblaze B2, use "s3.backblazeb2.com". S3-compatible storage costs 0.02 to 0.05 USD per GB per month, depending on provider and region.

Avoid misconfiguring storage. Common mistakes: using ReadWriteMany (RWX) when your storage class only supports ReadWriteOnce (RWO), this causes the pod to hang in Pending. Setting too small a size and running out of disk mid-migration. Forgetting credentials in your S3 config, which causes silent auth failures.

Running Ollama for Local LLM Inference (Optional)

Ollama runs large language models locally in your cluster. This lets Open WebUI use private LLMs without calling external APIs. Ollama is optional but powerful for teams that want data to stay on-premises.

Enable the Ollama sub-chart in your values.yaml:

ollama:
  enabled: true
  image: ollama/ollama:latest
  replicaCount: 1
  resources:
    requests:
      memory: "4Gi"
      cpu: "2"
    limits:
      memory: "8Gi"
      cpu: "4"
  persistence:
    enabled: true
    storageClass: "standard"
    size: 20Gi

Ollama needs at least 4GB RAM and 2 CPU cores per replica. GPU acceleration is available but requires GPU nodes in your cluster. Set GPU requests if you have NVIDIA or AMD GPU nodes:

resources:
  limits:
    nvidia.com/gpu: "1"

When Ollama runs in-cluster, Open WebUI discovers it automatically via the Kubernetes service mesh. You don't need to configure a separate endpoint.

Allocate 20Gi of storage for models. A single LLM like Mistral 7B takes 4GB, Llama 13B takes 7GB. Multiple models need proportionally more storage.

Run one replica of Ollama initially. If you scale Open WebUI to multiple replicas later, you can use an external Ollama server or scale Ollama with ReadWriteMany storage for model sharing. In-cluster Ollama is simpler but less scalable.

Alternatively, skip the sub-chart and configure the OLLAMA_API_BASE_URL environment variable to point to your Ollama deployment. This decouples Ollama from the Open WebUI release, making them easier to scale independently:

ollama:
  enabled: false

env:
  - name: OLLAMA_API_BASE_URL
    value: "your-ollama-server-endpoint"

Setting Up Ingress, TLS, and OIDC Authentication

Ingress exposes Open WebUI to the internet safely. Add ingress to values.yaml:

ingress:
  enabled: true
  className: "nginx"
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
  hosts:
    - host: "openwebui.example.com"
      paths:
        - path: /
          pathType: Prefix
  tls:
    - secretName: openwebui-tls
      hosts:
        - openwebui.example.com

Replace "openwebui.example.com" with your domain. This assumes you have cert-manager and NGINX ingress installed. If you don't, install them first using their official Helm repositories (jetstack for cert-manager and ingress-nginx for the controller). Both should be installed into their own namespaces before proceeding.

DNS must point your domain to the ingress controller's IP. Get the IP:

kubectl get svc -n ingress-nginx

Cert-manager automatically issues a Let's Encrypt certificate. TLS setup takes 2-5 minutes.

Enable OIDC for enterprise authentication. This lets users log in with Keycloak, Okta, Azure AD, or Google Workspace. Set these environment variables in your values.yaml to match your OIDC provider:

env:
  - name: WEBUI_AUTH
    value: "True"
  - name: OAUTH_PROVIDER_NAME
    value: "Azure AD"
  - name: OAUTH_CLIENT_ID
    value: "your-client-id"
  - name: OAUTH_CLIENT_SECRET
    valueFrom:
      secretKeyRef:
        name: oauth-secret
        key: client-secret

For Azure AD, also configure the provider's OAuth endpoints by setting environment variables for the provider base URL, authorization URL, token URL, and userinfo URL. Similar configurations apply for Keycloak, Okta, or Google Workspace - adjust the URLs to match your provider's OAuth2 endpoints.

Create a Kubernetes secret for the client secret:

kubectl create secret generic oauth-secret -n open-webui --from-literal=client-secret='your-secret'

Open WebUI will redirect unauthenticated users to your OIDC provider for login.

Safe Upgrades, Scaling, and Troubleshooting

Upgrade Open WebUI when new versions are released. Check available versions:

helm search repo open-webui/open-webui

Upgrade with one command:

helm upgrade open-webui open-webui/open-webui -n open-webui -f values.yaml

Helm automatically performs a rolling update: it stops one pod, starts the new version, then repeats for the next pod. For single-replica deployments, this causes brief downtime (30-90 seconds). Test upgrades on a dev cluster first.

Scale Open WebUI to multiple replicas for redundancy. Add this to values.yaml:

replicaCount: 3
resources:
  requests:
    memory: "1Gi"
    cpu: "500m"
  limits:
    memory: "2Gi"
    cpu: "1000m"

With three replicas and Redis enabled, Open WebUI survives node failures. One pod can be unavailable during upgrades while the other two keep serving traffic.

Common issues and fixes:

Pods stuck in Pending: Usually a storage class issue. Check PVC status:

kubectl describe pvc -n open-webui

If it says "no persistent volumes available", your storage class is misconfigured or doesn't exist on your cluster.

Connection refused errors: The service isn't listening yet. Wait 30 seconds and try again. If it persists, check logs:

kubectl logs -n open-webui deployment/open-webui

Out of disk space: Conversations or model files are full. Check PVC usage:

kubectl exec -it -n open-webui deployment/open-webui -- df -h

Resize the PVC if needed:

kubectl patch pvc open-webui -n open-webui -p '{"spec":{"resources":{"requests":{"storage":"20Gi"}}}}'

Ollama not found: Check the Ollama service is running:

kubectl get svc -n open-webui | grep ollama

If missing, the sub-chart didn't deploy. Verify it's enabled in values.yaml and reinstall.

When to Choose Managed Hosting Instead

Self-hosting Open WebUI on Kubernetes works well if you have cluster expertise and operations bandwidth. You control costs, keep data on-premises, and avoid vendor lock-in. It's a one-time setup plus occasional maintenance.

Managed hosting makes sense if you don't want to manage Kubernetes. Opsily's managed Open WebUI handles deployment, updates, backups, and scaling. You get a stable URL and SSL certificate without maintaining a cluster. Stellar Hosted charges EUR 49-199 per month depending on compute and storage.

For a 10-person team, running Open WebUI on Kubernetes costs roughly: cluster infrastructure (50 to 200 USD per month), storage (10 to 50 USD per month), and your labor for setup and troubleshooting (500 to 1000 USD one-time). Managed hosting typically costs 100 to 300 USD per month with no labor overhead. If your team doesn't have Kubernetes experience, managed hosting saves time and money in the first year.

You can also hybrid: run Open WebUI locally for development using Docker, and use managed hosting for production. This lets your team try it cheaply before committing to infrastructure.

Frequently Asked Questions

What are the prerequisites for deploying Open WebUI on Kubernetes with Helm?

You need a running Kubernetes cluster, kubectl configured to access it, and Helm 3.x. You should choose your storage backend (PVC or S3) and decide whether to use external PostgreSQL or the default SQLite. GPU support requires GPU nodes in your cluster.

How do I configure persistent storage in the Open WebUI Helm chart?

Set persistence.enabled: true in values.yaml and specify a storage class. Use PVC for single-cluster deployments and S3 for multi-cluster or cloud-native setups. PVC is simpler; S3 is more portable.

Can I run Ollama with Open WebUI on Kubernetes using the Helm chart?

Yes, enable the Ollama sub-chart in values.yaml. Allocate at least 4GB RAM and 2 CPU cores per replica. A single Ollama replica works for most setups. Models take 4-7GB per model, so provision storage accordingly.

How do I set up OIDC single sign-on with the Open WebUI Helm chart?

Set WEBUI_AUTH to True and configure OAUTH_PROVIDER_NAME, OAUTH_CLIENT_ID, and OAUTH_CLIENT_SECRET. Provide your OIDC provider's endpoints for authorization, token, and userinfo. Create a Kubernetes secret for the client secret. Open WebUI redirects users to your OIDC provider for login.

What's the best way to upgrade Open WebUI without downtime?

Run at least two replicas with persistent storage and Redis for session sharing. Run helm upgrade, which triggers a rolling update. One pod updates at a time while others serve traffic. Single-replica deployments have brief downtime during upgrades.

How do I troubleshoot pod failures or connection issues?

Check pod status with kubectl get pods, then inspect logs with kubectl logs. For Pending pods, verify your storage class exists. For connection errors, ensure the service is running and ingress is configured correctly. Use kubectl describe pod to see detailed error messages.

Should I run PostgreSQL inside the cluster or use a managed database service?

Managed PostgreSQL is easier and recommended for production. In-cluster PostgreSQL requires you to manage backups, upgrades, and scaling yourself. Managed services cost more but save operational overhead.

The Bottom Line

The Open WebUI Helm chart gives you a production-ready deployment in about 30 minutes once you understand storage, Ollama, and authentication options. The setup is straightforward if you're comfortable with Kubernetes. If you're not running a cluster or want to skip the ops work, check out Opsily's managed Open WebUI hosting instead.

Skip the Kubernetes overhead
Opsily manages Open WebUI deployments with automatic updates, backups, and scaling built in.
Explore Managed Hosting

Ready to self-host your own apps?

One server. Multiple apps. No per-app fees.

Get started →