Kubernetes
يأتي Libre WebUI بمخطط Helm في helm/libre-webui.
Work على Kubernetes
يعمل Work أصليًا على Kubernetes؛ فلا يتدخل أي عفريت Docker أو CLI أو مقبس. فعّله عند التثبيت:
helm install libre-webui ./helm/libre-webui --set work.enabled=true
يحوّل ذلك الخادم الخلفي إلى WORK_RUNTIME_BACKEND=kubernetes وينشئ:
- نطاقًا مخصصًا للعزل (
work.namespace، افتراضيًاlibre-webui-work) يحوي Pod لكل بيئة قيد التشغيل وPersistentVolumeClaim لكل مساحة مهمة (work.workspaceSize، افتراضيًا5Gi— حصة قرص فعلية لكل مهمة؛ ويمكن لسياسة Work مسماة تحديد حجم مختلف للمهام المنشأة تحتها)؛ - Role وRoleBinding ضمن النطاق يمنحان ServiceAccount للخادم بالضبط
pods(get/list/create/delete) وpods/exec(get/create) وpersistentvolumeclaims(get/list/create/delete) في ذلك النطاق — بلا أسرار ولا صلاحية على العنقود. تحل هذه المنحة محل مقبس Docker كليًا؛ فخادم API، لا التطبيق، يفرض عدم قدرة مواصفة البيئة المعزولة على تركيب مسارات المضيف؛ - NetworkPolicies ترفض افتراضيًا كل حركة البيئات، وتسمح بالدخول من الخادم الخلفي وحده على منفذ المعاينة، وتمنح البيئات الشبكية خروجًا إلى الإنترنت باستثناء
work.networkPolicy.blockedEgressCidrs(افتراضيًا النطاقات الخاصة وCGNAT الذي تستخدمه بعض العناقيد لـ CIDR الخاص بالـ Pod والخدمات ونطاق البيانات الوصفية المحلي للسحابة — تحقق من تغطية CIDR عنقودك). ولا يُسمح بـ DNS إلا إلىkube-system؛ ويحتاج العنقود ذو DNS محلي على العقد إلى استثناء خاص.
تعمل البيئات بلا جذر، وبنظام ملفات جذري للقراءة فقط، وبلا قدرات، مع seccomp RuntimeDefault ومن دون رمز ServiceAccount. تمر الملفات والأوامر وGit والطرفيات عبر مورد exec الفرعي لخادم API؛ وتُقدم المعاينة من عنوان Pod عبر الوكيل الموقّع من الأصل نفسه، ما يتطلب تشغيل الخادم داخل العنقود (بنية المخطط العادية). لا يدعم هذا الخادم مساحات عمل مجلد المضيف.
ملاحظتان للمشغّل. يتطلب إنفاذ NetworkPolicy واجهة CNI تنفذها (Calico وCilium وإصدارات kind الحديثة ومعظم افتراضيات العناقيد المُدارة)؛ تحقق قبل اعتبار العزل نشطًا، وتبلغ مجموعة الاختبارات الشاملة عما إذا كان العنقود ينفذها. ولا تركّب أبدًا مقبس بيئة الحاويات للعقدة في Pod الواجهة؛ فقد أُنشئ خادم Kubernetes ليجعل ذلك غير ضروري.
التثبيت
helm install libre-webui oci://ghcr.io/libre-webui/charts/libre-webui
ينشر المخطط الافتراضي Libre WebUI بتخزين دائم وخدمة Ollama مضمنة. انتقال 0.14.1 مثبت على بصمة صورته متعددة البنى المتحقق منها؛ وتستخدم المخططات اللاحقة افتراضيًا صورة appVersion الدلالية المطابقة. لا تضبط image.tag أو image.digest إلا إذا أردت صورة مختلفة عمدًا. وتأخذ image.tag غير الفارغة الأولوية على بصمة الانتقال.
يقبل ملف solo الافتراضي replicaCount: 0 لتعليق مقصود أو replicaCount: 1 للعمل العادي. ويرفض القيم الأكبر وHorizontalPodAutoscaler لأن SQLite والملفات المحلية والتنسيق داخل العملية غير آمنة خلف عدة Pods. ينشئ الإصدار بلا نسخ موارد التحكم لكنه لا يقدم حركة Libre WebUI.
لعدة نسخ، هيّئ ملف team كاملًا. يستخدم PostgreSQL/PGVector وتخزين كائنات متوافقًا مع S3 وRedis وعاملًا دائمًا منفصلًا؛ ويرفض المخطط خليطًا جزئيًا من الخلفيات المشتركة والمحلية. ابدأ بملف قيم محمي:
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 إدخال legacy تمامًا، وأن تحتوي خريطة المفاتيح STORAGE_ENCRYPTION_ACTIVE_KEY_ID. ويجب أن تكون secrets.jwtSecret قيمة واحدة ثابتة عالية العشوائية مشتركة بين كل Pods التطبيق والعامل؛ ويرفض المخطط وضع الفريق من دونها حتى لا تعتمد الجلسات على مواد مولدة داخل Pod. حافظ على TLS المتحقق لـ PostgreSQL المُدار؛ ولا تضف معاملات TLS للسائق إلى databaseUrl. تنطبق حدود التجمع على كل Pod، فاحجز على الأقل (replicaCount + worker.replicaCount) * POSTGRES_POOL_MAX اتصالًا مع هامش تشغيلي. ثبّت بملف القيم المحمي:
helm upgrade --install libre-webui \
oci://ghcr.io/libre-webui/charts/libre-webui \
--values /absolute/path/to/libre-team-values.yaml
لا تودع الملف ولا تمرر أسرار الإنتاج عبر --set. خزنه ضمن سير قيم مشفر ومحمي. وسّع مزوّدي النماذج وPods عزل Work بصورة مستقلة. عند work.enabled=true، يتلقى عامل الفريق الخارجي صورة التشغيل وStorageClass وحدود work.env نفسها التي تتلقاها Pods التطبيق. كما يتلقى نقطة Ollama المحلولة والمهل والسياق الأقصى المعتمد تلقائيًا نفسها، لأن تضمينات المستندات والمحادثات الدائمة وتشغيلات Work تنفذ استدعاءات المزوّد فيه. يتطلب تطبيق فريق نشط (replicaCount موجب أو توسيع تلقائي) عاملًا خارجيًا واحدًا على الأقل، ويرفض المخطط صفر عمال. اضبط replicaCount وworker.replicaCount كليهما على صفر للتعليق الكامل. أما صفر تطبيق مع عامل موجب فهو وضع تصريف أو استرداد للعامل فقط؛ لا يقدم الويب لكن يعالج العمل الدائم في الطابور.
ترقيات الفريق وتوافق المخطط
يدعم Libre سياسة إصدار مخطط دقيق، لا ترقيات مختلطة أو بلا توقف. يستخدم Deployment التطبيق والعامل Recreate لمنع تداخل القديم والجديد داخل كل Deployment، لكن Kubernetes لا ينسقهما كحد ترقية واحد. قبل الترقية، أوقف الدخول الجديد، واترك المهام الدائمة وWork تنتهي أو ألغها، وخفّض النشرين القديمين إلى صفر، وخذ نسخة فريق متحققة، وتأكد من انتهاء كل Pods القديمة. ثم رقِّ باستخدام POSTGRES_MIGRATION_MODE=apply؛ تمسك عملية جديدة قفل القائد الاستشاري في PostgreSQL وتنتظر العمليات الأخرى وتتحقق من سجل الترحيل نفسه. للتراجع، استعد النسخة المتحققة السابقة إلى هدف PostgreSQL/S3 نظيف؛ ولا توجّه برنامجًا أقدم إلى مخطط لا يدعمه بدقة. توقع توقف خدمة مقصودًا.
الوصول محليًا
kubectl port-forward svc/libre-webui 8080:8080
افتح http://localhost:8080.
Ollama خارجي
استخدم نقطة Ollama قائمة:
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
الأسرار
اضبط سر JWT ومفتاح تشفير ثابتين للإنتاج. ينشئ المخطط افتراضيًا <release>-libre-webui-secrets من قيم secrets.* غير الفارغة:
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)"
لـ Secret يديره المشغّل، اضبط secrets.existingSecret. لا يعرض المخطط Secret حينها، وتشير Pods التطبيق والعامل إلى الكائن المسمى:
secrets:
existingSecret: libre-webui-runtime
أنشئ Secret قبل التثبيت. يجب أن يحتوي jwt-secret وencryption-key. ويتطلب وضع الفريق أيضًا database-url وredis-url وstorage-encryption-keys. المفاتيح الاختيارية هي session-secret وs3-access-key-id وs3-secret-access-key وs3-session-token. ويمكن لـ OAuth GitHub وHugging Face قراءة أزواج *-client-id و*-client-secret من Secret عند تفعيل التكامل بقيمة secrets.githubClientId أو secrets.huggingfaceClientId غير فارغة. لا يتحقق المخطط من قيم Secret أو ينسخها عمدًا؛ ويمنع غياب مفتاح مطلوب Pod من البدء.
لأتمتة الإنتاج، فضّل secrets.existingSecret مع متحكم أسرار خارجي، أو مرر قيمًا ثابتة في سير Helm مشفر. قد تظهر قيم --set في فحص العمليات وتُحفظ في بيانات إصدار Helm. أضف بيانات المزوّدين عبر امتداد مقصود للمخطط أو هيئ بيانات كل مستخدم في WebUI.
NetworkPolicies للتطبيق والعامل
اضبط networkPolicy.enabled=true لعرض سياسات دخول للتطبيق ولعامل الفريق الخارجي:
networkPolicy:
enabled: true
يقبل التطبيق الدخول على منفذ HTTP للحاوية فقط، ولا يقبل العامل أي دخول. ولا تقيد السياسات الخروج؛ فما تزال العمليات بحاجة إلى PostgreSQL وRedis وS3 وOllama والأدوات ومزوّدي النماذج، ويحدد المشغّلون أماكنها.
هذا الإعداد منفصل عن work.networkPolicy.enabled الذي يتحكم بسياسات الرفض الافتراضي في نطاق Work ويُفعل افتراضيًا عند تفعيل Work. ويتطلب الاثنان CNI ينفذ Kubernetes NetworkPolicy فعلًا؛ عرض الكائنات وحده لا يثبت العزل.
الاستمرارية
احتفظ بـ PVC بيانات Libre WebUI وPVC نماذج Ollama على تخزين دائم. وانسخ وحدة بيانات Libre WebUI ومفتاح التشفير احتياطيًا معًا.
توجد مساحات مهام Work في PVC خاصة بها ضمن نطاق العزل، لا PVC بيانات Libre WebUI. وتحتاج الاستعادة الكاملة قاعدة البيانات (الملكية وأسماء الموارد والتشغيلات) وتلك PVC؛ انسخها معًا بالسياسة نفسها.
Ingress
للوصول العام، هيئ Ingress مع HTTPS واضبط أصل المتصفح الدقيق عبر المخطط:
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 عدد قفزات دقيق، لا قيمة منطقية. افتراضي المخطط الآمن 0 يتجاهل عناوين العملاء المُمررة. استخدم 1 فقط إذا اتصل وكيل Ingress واحد مباشرة بـ Libre؛ واحسب كل موازن أو وكيل موثوق في سلسلة أطول ثابتة، وأبقِ Service غير متاح خارجها. العدد الأصغر يجمع العملاء خلف عنوان الوكيل وقد يستنفد حدود الدخول المشتركة؛ والأكبر قد يثق بعنوان يرسله العميل. يقبل المخطط 0 إلى 16 فقط، لا true غير المحدود، ويرسله إلى Pods HTTP وحدها.
لا يعرض المخطط الحالي BASE_URL أو عناوين استدعاء OAuth. يجب أن توسع عمليات OAuth المخطط أو ترقع Deployment لضبطها، وأن تطابق عناوين الاستدعاء النطاق العام.
تخطيط الموارد
لـ Ollama محلي داخل العنقود، جدوِل Pod على عقد بذاكرة وقدرة GPU كافيتين للنماذج. وإذا كان العنقود يملك خدمة Ollama أو استدلال مخصصة، فعادة يكون Ollama الخارجي أبسط.