Kubernetes
Libre WebUI fournit un chart Helm dans helm/libre-webui.
Work sur Kubernetes
Work s’exécute nativement sur Kubernetes : aucun démon, client en ligne de commande ni socket Docker n’intervient. Activez-le lors de l’installation :
helm install libre-webui ./helm/libre-webui --set work.enabled=true
Cette commande définit le serveur dorsal sur WORK_RUNTIME_BACKEND=kubernetes et crée :
- un espace de noms dédié aux environnements isolés (
work.namespace, valeur par défautlibre-webui-work) contenant un pod par environnement en cours d’exécution et un PersistentVolumeClaim par espace de travail de tâche (work.workspaceSize, valeur par défaut5Gi— un véritable quota de disque propre à chaque tâche ; une politique Work nommée peut définir une taille différente pour les tâches créées sous cette politique) ; - un Role et un RoleBinding limités à cet espace de noms, qui accordent au ServiceAccount du serveur dorsal exactement les droits
pods(get/list/create/delete),pods/exec(get/create) etpersistentvolumeclaims(get/list/create/delete) dans cet espace de noms — aucun secret ni accès à l’échelle du cluster. Cette autorisation remplace entièrement le socket Docker : le serveur d’API, et non l’application, garantit qu’une spécification d’environnement isolé ne peut pas monter de chemins de l’hôte ; - des NetworkPolicies qui refusent par défaut tout trafic des environnements isolés, autorisent le trafic entrant uniquement depuis le serveur dorsal sur le port de l’aperçu et permettent aux environnements avec accès réseau de sortir vers Internet, à l’exception de
work.networkPolicy.blockedEgressCidrs(par défaut, les plages privées, la plage CGNAT que certains clusters gérés emploient pour les CIDR des pods et services, ainsi que la plage locale de métadonnées cloud — vérifiez que les CIDR des pods et services de votre cluster sont couverts). Le DNS des environnements isolés n’est autorisé que verskube-system; un cluster qui exécute un DNS local à chaque nœud nécessite sa propre exception DNS.
Les environnements isolés s’exécutent sans privilèges racine, avec un système de fichiers racine en lecture seule, toutes les capacités supprimées, seccomp RuntimeDefault et aucun jeton ServiceAccount. Les fichiers, commandes, opérations Git et terminaux interactifs utilisent la sous-ressource exec par l’intermédiaire du serveur d’API. L’aperçu est servi depuis l’adresse IP du pod isolé par le proxy signé de même origine, ce qui exige l’exécution du serveur dorsal dans le cluster (topologie normale du chart). Les espaces de travail correspondant à des dossiers de l’hôte ne sont pas pris en charge par ce serveur dorsal.
Deux remarques pour les opérateurs. L’application des NetworkPolicies exige une interface réseau de conteneur qui les met en œuvre (Calico, Cilium, versions récentes de kind et valeurs par défaut de la plupart des clusters gérés) : vérifiez votre cluster avant de considérer l’isolation des environnements comme active ; la suite de bout en bout de l’intégration continue indique si le cluster sur lequel elle s’exécute les applique. Par ailleurs, ne montez jamais le socket de l’environnement d’exécution de conteneurs d’un nœud dans le pod de la WebUI ; le serveur dorsal Kubernetes existe précisément pour rendre cela inutile.
Installation
helm install libre-webui oci://ghcr.io/libre-webui/charts/libre-webui
Le chart par défaut déploie Libre WebUI avec un stockage persistant et un service Ollama intégré. La transition 0.14.1 est fixée à l’empreinte vérifiée de son image multi-architecture ; les charts suivants utilisent par défaut l’image dont la valeur sémantique appVersion correspond. Ne définissez explicitement image.tag ou image.digest que si vous souhaitez volontairement une autre image. Une valeur image.tag non vide est prioritaire sur l’empreinte de transition.
Le profil solo par défaut accepte replicaCount: 0 pour une suspension volontaire ou replicaCount: 1 pour un fonctionnement normal. Il refuse les valeurs supérieures et HorizontalPodAutoscaler, car SQLite, les fichiers locaux et la coordination interne au processus ne sont pas sûrs derrière plusieurs pods. Une version sans réplique configure les ressources de son plan de contrôle, mais ne dessert aucun trafic Libre WebUI.
Pour plusieurs répliques, configurez le profil team complet. Il utilise PostgreSQL/PGVector, un stockage d’objets binaires compatible avec S3, Redis et un processus de travail durable séparé ; le chart refuse tout mélange partiel de serveurs dorsaux partagés et locaux. Commencez par un fichier de valeurs protégé comme celui-ci :
replicaCount: 3
env:
LIBRE_PLATFORM_MODE: team
DATABASE_BACKEND: postgres
DATABASE_SSL_MODE: verify-full
POSTGRES_MIGRATION_MODE: apply
POSTGRES_POOL_MAX: 10
POSTGRES_CONNECT_TIMEOUT_MS: 5000
POSTGRES_IDLE_TIMEOUT_MS: 30000
POSTGRES_STATEMENT_TIMEOUT_MS: 30000
POSTGRES_MIGRATION_LOCK_TIMEOUT_MS: 60000
OLLAMA_TIMEOUT: 300000
OLLAMA_LONG_OPERATION_TIMEOUT: 900000
OLLAMA_MAX_CONTEXT: 32768
BLOB_STORE_BACKEND: s3
VECTOR_STORE_BACKEND: pgvector
COORDINATION_BACKEND: redis
JOB_WORKER_MODE: external
STORAGE_ENCRYPTION_ACTIVE_KEY_ID: active
S3_BUCKET: libre-blobs
S3_REGION: us-east-1
S3_BLOB_PREFIX: libre/blobs
worker:
replicaCount: 1
secrets:
databaseUrl: postgresql://libre:replace-me@postgres.example/libre
redisUrl: rediss://redis.example:6379/0
jwtSecret: '<one-stable-high-entropy-secret-for-every-replica>'
encryptionKey: '<legacy-64-character-lowercase-hex-key>'
storageEncryptionKeys: '{"legacy":"<legacy-64-character-lowercase-hex-key>","active":"<active-64-character-lowercase-hex-key>"}'
s3AccessKeyId: replace-me
s3SecretAccessKey: replace-me
secrets.encryptionKey doit correspondre exactement à l’entrée legacy, et la liste des clés doit également contenir STORAGE_ENCRYPTION_ACTIVE_KEY_ID. secrets.jwtSecret doit être une valeur stable à forte entropie, commune à tous les pods d’application et de traitement ; le chart refuse le mode équipe en son absence afin que les sessions ne dépendent jamais de données générées localement par un pod. Conservez une vérification TLS pour PostgreSQL géré ; n’ajoutez pas de paramètres TLS de pilote à databaseUrl. Les limites du pool s’appliquent à chaque pod d’application et de traitement. Réservez donc au moins (replicaCount + worker.replicaCount) * POSTGRES_POOL_MAX connexions à la base de données, auxquelles s’ajoute une marge opérationnelle. Installez avec le fichier de valeurs protégé :
helm upgrade --install libre-webui \
oci://ghcr.io/libre-webui/charts/libre-webui \
--values /absolute/path/to/libre-team-values.yaml
Ne validez pas ce fichier dans le dépôt et ne transmettez pas les secrets de production avec --set. Stockez-le selon une procédure protégée de chiffrement des valeurs. Mettez à l’échelle les fournisseurs de modèles et les pods isolés Work indépendamment. Lorsque work.enabled=true, le processus de traitement d’équipe externe reçoit la même image d’exécution, la même StorageClass et les mêmes limites work.env que les pods d’application. Il reçoit aussi le même point de terminaison Ollama résolu, les mêmes délais de requête et le même contexte maximal adopté automatiquement que l’application, car les plongements de documents, les discussions durables et les exécutions Work y effectuent leurs appels aux fournisseurs. Une application d’équipe active (replicaCount positif ou mise à l’échelle automatique activée) exige au moins un processus de travail externe ; le chart refuse une configuration sans processus de travail avant l’installation. Définissez replicaCount et worker.replicaCount sur zéro pour une suspension complète. Définir uniquement le nombre d’applications sur zéro constitue un mode volontaire de vidage ou de récupération réservé au processus de travail : aucun trafic web n’est servi, mais le traitement des tâches durables en file d’attente continue.
Mises à niveau d’équipe et compatibilité des schémas
Libre applique une politique de version exacte du schéma et ne prend en charge ni plusieurs versions simultanées, ni les mises à niveau de base de données sans interruption. Les Deployments de l’application et du processus de travail externe utilisent chacun Recreate, ce qui empêche les anciens et les nouveaux pods de se chevaucher au sein d’un même Deployment. Kubernetes ne coordonne toutefois pas les deux Deployments comme une seule frontière de mise à niveau. Avant la mise à niveau, arrêtez les nouvelles entrées, laissez se terminer ou annulez les tâches durables et Work actives, réduisez les deux anciens Deployments à zéro, effectuez une sauvegarde d’équipe vérifiée et confirmez l’arrêt de tous les anciens pods d’application et de traitement. Vous pouvez alors mettre à niveau la version avec POSTGRES_MIGRATION_MODE=apply ; un nouveau processus détient le verrou de coordination PostgreSQL tandis que tous les autres nouveaux processus attendent et valident le même registre de migrations. Pour revenir en arrière, restaurez la sauvegarde vérifiée précédente dans une cible PostgreSQL/S3 propre ; ne dirigez jamais un ancien binaire vers un schéma qu’il ne prend pas exactement en charge. Cette procédure entraîne une interruption volontaire du service.
Accès local
kubectl port-forward svc/libre-webui 8080:8080
Ouvrez http://localhost:8080.
Ollama externe
Utilisez un point de terminaison Ollama existant :
helm install libre-webui oci://ghcr.io/libre-webui/charts/libre-webui \
--set ollama.bundled.enabled=false \
--set ollama.external.enabled=true \
--set ollama.external.url=http://my-ollama:11434
Secrets
Définissez un secret JWT et une clé de chiffrement stables pour la production. Par défaut, le chart crée <release>-libre-webui-secrets à partir des valeurs secrets.* non vides :
helm upgrade --install libre-webui \
oci://ghcr.io/libre-webui/charts/libre-webui \
--set-string secrets.jwtSecret="$(openssl rand -hex 64)" \
--set-string secrets.encryptionKey="$(openssl rand -hex 32)"
Pour un Secret géré par un opérateur, définissez secrets.existingSecret. Le chart ne produit alors aucun Secret, et les pods de l’application et du processus de travail référencent l’objet nommé :
secrets:
existingSecret: libre-webui-runtime
Créez ce Secret avant d’installer la version. Il doit contenir jwt-secret et encryption-key. Le mode équipe exige en plus database-url, redis-url et storage-encryption-keys. Les clés facultatives reconnues par le chart sont session-secret, s3-access-key-id, s3-secret-access-key et s3-session-token. OAuth GitHub et Hugging Face peuvent également lire leurs paires *-client-id et *-client-secret depuis le Secret nommé lorsque la valeur non vide correspondante secrets.githubClientId ou secrets.huggingfaceClientId active l’intégration. Le chart ne valide ni ne copie volontairement les valeurs du Secret ; si une clé requise manque, le pod ne peut pas démarrer.
Pour automatiser la production, préférez secrets.existingSecret avec un contrôleur de secrets externes ou fournissez des valeurs stables selon une procédure Helm de valeurs chiffrées. Les valeurs --set de la ligne de commande peuvent apparaître lors de l’inspection des processus et sont conservées dans les métadonnées des versions Helm. Ajoutez les identifiants des fournisseurs par une extension volontaire du chart ou configurez des identifiants propres à chaque utilisateur dans la WebUI.
NetworkPolicies de l’application et du processus de travail
Définissez networkPolicy.enabled=true pour produire des politiques de trafic entrant destinées à l’application et, en mode équipe, au processus de travail durable externe :
networkPolicy:
enabled: true
L’application accepte le trafic entrant uniquement sur le port HTTP de son conteneur. Le processus de travail n’accepte aucun trafic entrant. Ces politiques ne limitent pas le trafic sortant : les processus d’application et de travail doivent toujours pouvoir joindre les points de terminaison PostgreSQL, Redis, S3, Ollama, d’outils et de fournisseurs de modèles configurés, et les opérateurs choisissent l’emplacement de ces services.
Ce paramètre est distinct de work.networkPolicy.enabled, qui contrôle les politiques de refus par défaut dans l’espace de noms des environnements isolés Work et est activé par défaut lorsque Work l’est. Les deux paramètres exigent une interface réseau de conteneur qui applique réellement les NetworkPolicies Kubernetes ; produire les objets ne prouve pas à lui seul l’isolation du réseau.
Persistance
Conservez le PVC de données de Libre WebUI et le PVC des modèles Ollama dans un stockage persistant. Sauvegardez ensemble le volume de données de Libre WebUI et la clé de chiffrement.
Les espaces de travail des tâches Work résident dans leurs propres PVC, dans l’espace de noms des environnements isolés, et non dans le PVC de données de Libre WebUI. Une restauration complète de Work nécessite la base de données (propriété des tâches, noms des ressources, exécutions) et ces PVC ; sauvegardez-les ensemble selon la même politique.
Ingress
Pour un accès public, configurez Ingress avec HTTPS et définissez l’origine exacte du navigateur au moyen du chart :
helm upgrade libre-webui \
oci://ghcr.io/libre-webui/charts/libre-webui \
--reuse-values \
--set env.TRUST_PROXY=1 \
--set-string env.CORS_ORIGIN=https://your-domain.example
TRUST_PROXY est un nombre exact de sauts, et non une valeur booléenne. La valeur sûre par défaut du chart, 0, ignore les adresses clientes transférées. N’utilisez 1 que lorsqu’un seul proxy Ingress se connecte directement à Libre ; comptez chaque saut de répartiteur de charge ou de proxy fiable dans une chaîne fixe plus longue et maintenez le Service inaccessible en dehors de cette chaîne. Une valeur trop faible regroupe les clients sous l’adresse d’un proxy et peut épuiser les limites de connexion communes ; une valeur trop élevée peut faire confiance à une adresse fournie par le client. Le chart n’accepte que les valeurs de 0 à 16, jamais la valeur illimitée true, et n’envoie la valeur qu’aux pods d’application HTTP.
Le chart actuel n’expose ni BASE_URL, ni les URL de rappel OAuth. Les déploiements utilisant OAuth doivent étendre le chart ou corriger le Deployment pour définir ces variables, et les URL de rappel doivent correspondre au domaine public.
Planification des ressources
Pour une instance Ollama locale dans le cluster, planifiez le pod Ollama sur des nœuds disposant de suffisamment de mémoire et de capacité graphique pour les modèles que vous comptez exécuter. Si votre cluster possède déjà un service Ollama ou d’inférence dédié, une instance Ollama externe est généralement plus simple.