--- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: openwebui-data namespace: openwebui spec: accessModes: - ReadWriteOnce storageClassName: hcloud-volumes-encrypted resources: requests: storage: 10Gi --- apiVersion: apps/v1 kind: Deployment metadata: name: openwebui namespace: openwebui labels: app: openwebui spec: replicas: 1 strategy: type: Recreate selector: matchLabels: app: openwebui template: metadata: labels: app: openwebui spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: csi.hetzner.cloud/location operator: In values: - fsn1 initContainers: - name: wait-for-postgres image: postgres:16-alpine command: - sh - -c - | until pg_isready -h openwebui-postgres -p 5432 -U "$POSTGRES_USER"; do echo "Waiting for openwebui-postgres..."; sleep 2; done env: - name: POSTGRES_USER valueFrom: secretKeyRef: name: openwebui-postgres-credentials key: POSTGRES_USER - name: wait-for-redis image: redis:7-alpine command: - sh - -c - | until redis-cli -h openwebui-redis -p 6379 ping | grep -q PONG; do echo "Waiting for openwebui-redis..."; sleep 2; done containers: - name: openwebui image: ghcr.io/open-webui/open-webui:v0.11.3 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 8080 env: # Core - name: PORT value: "8080" - name: WEBUI_URL value: "https://openwebui.basicstack.de" - name: WEBUI_SECRET_KEY valueFrom: secretKeyRef: name: openwebui-app-secrets key: WEBUI_SECRET_KEY - name: ENV value: "prod" - name: WEBUI_AUTH value: "true" - name: ENABLE_SIGNUP value: "false" - name: ENABLE_LOGIN_FORM value: "false" # Database (Postgres) - name: DATABASE_URL valueFrom: secretKeyRef: name: openwebui-app-secrets key: DATABASE_URL # Vector DB (pgvector) - name: VECTOR_DB value: "pgvector" - name: PGVECTOR_DB_URL valueFrom: secretKeyRef: name: openwebui-app-secrets key: PGVECTOR_DB_URL - name: PGVECTOR_CREATE_EXTENSION value: "true" # Redis (main + websocket manager) - name: REDIS_URL valueFrom: secretKeyRef: name: openwebui-app-secrets key: REDIS_URL - name: ENABLE_WEBSOCKET_SUPPORT value: "true" - name: WEBSOCKET_MANAGER value: "redis" - name: WEBSOCKET_REDIS_URL valueFrom: secretKeyRef: name: openwebui-app-secrets key: WEBSOCKET_REDIS_URL # Object Storage (Hetzner S3-compatible) - name: STORAGE_PROVIDER value: "s3" - name: S3_BUCKET_NAME valueFrom: secretKeyRef: name: openwebui-s3 key: bucket - name: S3_REGION_NAME valueFrom: secretKeyRef: name: openwebui-s3 key: region - name: S3_ENDPOINT_URL valueFrom: secretKeyRef: name: openwebui-s3 key: endpoint - name: S3_ACCESS_KEY_ID valueFrom: secretKeyRef: name: openwebui-s3 key: access-key - name: S3_SECRET_ACCESS_KEY valueFrom: secretKeyRef: name: openwebui-s3 key: secret-key - name: S3_ADDRESSING_STYLE value: "path" - name: S3_USE_ACCELERATE_ENDPOINT value: "false" # OIDC (Pocket ID) - name: ENABLE_OAUTH_SIGNUP value: "true" - name: OAUTH_MERGE_ACCOUNTS_BY_EMAIL value: "true" - name: OAUTH_UPDATE_PICTURE_ON_LOGIN value: "true" - name: DEFAULT_USER_ROLE value: "user" - name: OAUTH_PROVIDER_NAME value: "Pocket ID" - name: OPENID_PROVIDER_URL value: "https://auth.basicstack.de/.well-known/openid-configuration" - name: OAUTH_SCOPES value: "openid email profile groups" - name: OAUTH_CLIENT_ID valueFrom: secretKeyRef: name: openwebui-oidc key: client-id - name: OAUTH_CLIENT_SECRET valueFrom: secretKeyRef: name: openwebui-oidc key: client-secret - name: ENABLE_OAUTH_ROLE_MANAGEMENT value: "true" - name: ENABLE_OAUTH_GROUP_MANAGEMENT value: "true" - name: ENABLE_OAUTH_GROUP_CREATION value: "true" - name: OAUTH_ROLES_CLAIM value: "groups" - name: OAUTH_ALLOWED_ROLES value: "openwebui_users,openwebui_admins" - name: OAUTH_ADMIN_ROLES value: "openwebui_admins" - name: OAUTH_GROUPS_CLAIM value: "groups" # Runtime - name: UVICORN_WORKERS value: "1" volumeMounts: - name: openwebui-data mountPath: /app/backend/data resources: requests: cpu: 250m memory: 1Gi limits: cpu: 2000m memory: 4Gi startupProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 60 livenessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 60 periodSeconds: 30 timeoutSeconds: 10 failureThreshold: 5 readinessProbe: httpGet: path: /health/db port: 8080 initialDelaySeconds: 20 periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 6 volumes: - name: openwebui-data persistentVolumeClaim: claimName: openwebui-data --- apiVersion: v1 kind: Service metadata: name: openwebui namespace: openwebui labels: app: openwebui spec: type: ClusterIP selector: app: openwebui ports: - name: http port: 80 targetPort: 8080 protocol: TCP --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: openwebui namespace: openwebui annotations: cert-manager.io/cluster-issuer: "letsencrypt-prod" traefik.ingress.kubernetes.io/router.entrypoints: websecure spec: ingressClassName: traefik tls: - hosts: - openwebui.basicstack.de secretName: openwebui-tls rules: - host: openwebui.basicstack.de http: paths: - path: / pathType: Prefix backend: service: name: openwebui port: number: 80