Création d’un RAG Confluence via crawl automatique sous OpenWebUI

Déployez un pipeline RAG pour Confluence avec OpenWebUI : crawl automatique, PAT Confluence, Kubernetes + Argo CD, vector store Faiss, embeddings locaux.


Pourquoi un RAG Confluence ?

  • RAG (Retrieval-Augmented Generation) : combine un moteur de recherche sémantique et un LLM pour des réponses factuelles avec citations.
  • Confluence : référentiel documentaire critique (procédures, PJ PDF, etc.).
  • OpenWebUI + Llama-Index : interface full-web, auto-reload des documents, embeddings CamemBERT => souveraineté & coût réduit.

Mots-clés SEO : RAG Confluence, OpenWebUI, Llama-Index, Kubernetes, Argo CD, CamemBERT embeddings, crawl Confluence.


Pré-requis techniques

ÉlémentVersion conseillée
Kubernetes≥ 1.24
Argo CD≥ 2.8
Helm≥ 3.13
ConfluenceCloud ou DC avec REST v2
Navigateur headlessPlaywright + Chromium
PVC (RWX)10 Go minimum

Génération d’un Personal Access Token Confluence

  1. Connectez-vous à Confluence.
  2. En haut à droite : Profile ▸ Settings.
  3. Menu latéral : Security ▸ Personal access tokens.
  4. Create token
    • Label : openwebui-crawler
    • Expiry : 12 mois
    • Scopes : read:confluence-content
  5. Copiez le token (il n’est montré qu’une fois) et stockez-le dans un Secret Kubernetes :
kubectl -n ai-rag create secret generic confluence-credentials \
  --from-literal=CONFLUENCE_API_TOKEN="<votre_token>"

(namespace exemple ai-rag à adapter)


Déploiement du crawler automatique

Scripts publics

RôleLien brut GitHub
Crawler Confluencehttps://raw.githubusercontent.com/pmietlicki/docs-crawler/refs/heads/main/confluence.py

Manifestes Kubernetes

# --- stockage partagé -------------------------------------------------------
apiVersion: v1
kind: PersistentVolumeClaim
metadata: { name: rag-confluence-pvc, namespace: ai-rag }
spec:
  accessModes: [ ReadWriteMany ]
  resources: { requests: { storage: 10Gi } }

# --- dépendances Python du crawler ------------------------------------------
apiVersion: v1
kind: ConfigMap
metadata: { name: confluence-crawler-requirements, namespace: ai-rag }
data:
  requirements.txt: |
    requests
# --- CronJob nightly ---------------------------------------------------------
apiVersion: batch/v1
kind: CronJob
metadata: { name: confluence-crawler, namespace: ai-rag }
spec:
  schedule: "0 2 * * *"           # 02h00 locale
  concurrencyPolicy: Forbid
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 3
  jobTemplate:
    spec:
      template:
        metadata: { labels: { app: confluence-crawler } }
        spec:
          restartPolicy: Never
          serviceAccountName: docs-crawler-sa
          volumes:
            - name: repo
              emptyDir: {}
            - name: confluence-pvc
              persistentVolumeClaim: { claimName: rag-confluence-pvc }
            - name: requirements
              configMap: { name: confluence-crawler-requirements }
          initContainers:
            - name: clone-crawler
              image: alpine/git:latest
              command:
                - sh
                - -ec
                - |
                  git clone --depth 1 https://github.com/pmietlicki/docs-crawler /repo
              volumeMounts:
                - { name: repo, mountPath: /repo }
          containers:
            - name: crawler
              image: python:3.11-slim
              workingDir: /repo
              env:
                - { name: PYTHONUNBUFFERED, value: "1" }
                - { name: CONFLUENCE_API_TOKEN,
                    valueFrom: { secretKeyRef: { name: confluence-credentials, key: CONFLUENCE_API_TOKEN } } }
                - { name: CONFLUENCE_URL, value: "https://confluence.exemple.local" }
                - { name: EXPORT_BASE_DIR, value: /data/confluence }
              volumeMounts:
                - { name: repo, mountPath: /repo }
                - { name: confluence-pvc, mountPath: /data }
                - { name: requirements, mountPath: /tmp/req, readOnly: true }
              command:
                - sh
                - -ec
                - |
                  pip install --no-cache-dir -r /tmp/req/requirements.txt
                  python confluence.py

Déploiement du pipeline RAG OpenWebUI

Script Python

RôleLien brut GitHub
Pipeline RAGhttps://raw.githubusercontent.com/pmietlicki/openwebui-pipelines/refs/heads/main/custom_rag_pipeline.py

Application Argo CD

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata: { name: openwebui-rag-confluence, namespace: argocd }
spec:
  project: default
  destination:
    server: https://kubernetes.default.svc
    namespace: ai-rag
  sources:
    - repoURL: https://helm.openwebui.com
      chart: pipelines
      targetRevision: "0.*"
      helm:
        releaseName: openwebui-rag-confluence
        values: |
          extraEnvVars:
            - { name: PIPELINE_TITLE, value: "Confluence" }
            - { name: PIPELINES_URLS, value: "https://raw.githubusercontent.com/pmietlicki/openwebui-pipelines/refs/heads/main/custom_rag_pipeline.py" }
            - { name: DOCS_DIR, value: "/app/pipelines/confluence" }
            - { name: VECTOR_INDEX_DIR, value: "/app/pipelines/index/confluence" }
            - { name: EMBED_MODEL_TYPE, value: "local" }
            - { name: LOCAL_EMBED_MODEL_NAME, value: "dangvantuan/sentence-camembert-base" }
            - { name: FORCE_INITIAL, value: "true" }
            - { name: MISTRAL_API_KEY, value: "XXXXXXXXXXXX" }
          persistence:
            enabled: true
            existingClaim: rag-confluence-pvc
  syncPolicy:
    automated: { prune: true, selfHeal: true }
    syncOptions: [ CreateNamespace=true ]

Vérification & bonnes pratiques

ActionCommande
Lancer un crawl manuelkubectl create job --from=cronjob/confluence-crawler manual-crawl -n ai-rag
Suivre les logskubectl logs -f job/manual-crawl -n ai-rag
Taille du PVCkubectl exec -n ai-rag deploy/openwebui-rag-confluence -- df -h /app/pipelines

Ajout dans OpenWebUI

Intégration du pipeline RAG dans OpenWebUI

Une fois votre CronJob “confluence-crawler” et l’instance Helm openwebui-pipelines-confluence déployés, il reste à raccorder la passerelle Pipelines à l’interface OpenWebUI :

  1. Repérer l’URL du service Pipelines
    Dans Kubernetes, le chart expose le conteneur sur le port 9099.
    Exemple : http://openwebui-pipelines-confluence.ai-rag.svc.cluster.local:9099.
  2. Déclarer la connexion dans OpenWebUI
    • Connectez-vous en adminSettings › Connections.
    • Cliquez + puis remplissez :
      • API Base URL : http://<service-pipelines>:9099
      • API key : 0p3n-w3bu! (valeur fixe côté Pipelines)
    • Validez ; un pictogramme “Pipelines” apparaît si la connexion est opérationnelle. (Open WebUI)
  3. Activer/paramétrer les pipelines
    Dans Settings › Pipelines, vous pouvez — sans redéploiement —
    • (dés)activer un pipeline,
    • ajuster les valves (variables dynamiques exposées par le script Python). (Open WebUI)
  4. Vérifier la disponibilité du modèle “Confluence”
    Ouvrez Workspace › Models : le modèle déclaré dans PIPELINE_TITLE (“Confluence”) est listé automatiquement. Sélectionnez-le pour vos chats ; les requêtes passeront alors par votre RAG propriétaire.

Astuce : si vous n’utilisez pas Helm, un déploiement Docker rapide reste possible :
docker run -d -p 9099:9099 -e PIPELINES_URLS="https://raw.githubusercontent.com/pmietlicki/openwebui-pipelines/refs/heads/main/custom_rag_pipeline.py" ghcr.io/open-webui/pipelines:main (zabirauf || Zohaib)


En suivant ces quatre étapes, votre instance OpenWebUI exploite désormais le RAG Confluence sans fuite d’information hors cluster : les requêtes partent vers le service Pipelines interne, lequel interroge l’index FAISS généré par le crawler.


FAQ rapide

QuestionRéponse courte
Le PAT expire, que faire ?Recréez-en un, puis kubectl delete secret… / create secret…
Peut-on filtrer par espace ?Définissez SPACE_KEY_FILTER=HR dans le CronJob.
Chiffrement PVC ?Activez la classe de stockage enc-rwx si disponible.

Conclusion

Vous disposez désormais d’un RAG Confluence clé en main :

  • Crawl automatique + stockage partagé.
  • Index vectoriel mis à jour sans intervention.
  • Réponses précises, citées, en français.

Gain de temps utilisateur, souveraineté des embeddings, coût API réduit.