From ca5c681f5b30a9a8bb5936216b643b4eb3e7a73d Mon Sep 17 00:00:00 2001 From: phact Date: Tue, 9 Dec 2025 23:35:05 -0500 Subject: [PATCH 01/21] v0 --- helm/openrag/Chart.yaml | 18 + helm/openrag/templates/NOTES.txt | 80 ++++ helm/openrag/templates/_helpers.tpl | 163 +++++++ .../openrag/templates/backend/deployment.yaml | 273 ++++++++++++ helm/openrag/templates/backend/service.yaml | 18 + .../configmaps/app-config-configmap.yaml | 39 ++ .../configmaps/flow-ids-configmap.yaml | 14 + .../templates/dashboards/deployment.yaml | 81 ++++ .../openrag/templates/dashboards/service.yaml | 18 + .../templates/frontend/deployment.yaml | 80 ++++ helm/openrag/templates/frontend/hpa.yaml | 33 ++ helm/openrag/templates/frontend/service.yaml | 18 + helm/openrag/templates/ingress/ingress.yaml | 104 +++++ .../templates/langflow/deployment.yaml | 211 +++++++++ helm/openrag/templates/langflow/service.yaml | 18 + .../openrag/templates/secrets/aws-secret.yaml | 13 + .../templates/secrets/langflow-secret.yaml | 14 + .../secrets/llm-providers-secret.yaml | 22 + .../templates/secrets/oauth-secret.yaml | 19 + .../templates/secrets/opensearch-secret.yaml | 13 + helm/openrag/templates/serviceaccount.yaml | 13 + .../openrag/templates/storage/config-pvc.yaml | 18 + .../templates/storage/documents-pvc.yaml | 18 + helm/openrag/templates/storage/keys-pvc.yaml | 18 + .../templates/storage/langflow-pvc.yaml | 18 + helm/openrag/values.yaml | 407 ++++++++++++++++++ 26 files changed, 1741 insertions(+) create mode 100644 helm/openrag/Chart.yaml create mode 100644 helm/openrag/templates/NOTES.txt create mode 100644 helm/openrag/templates/_helpers.tpl create mode 100644 helm/openrag/templates/backend/deployment.yaml create mode 100644 helm/openrag/templates/backend/service.yaml create mode 100644 helm/openrag/templates/configmaps/app-config-configmap.yaml create mode 100644 helm/openrag/templates/configmaps/flow-ids-configmap.yaml create mode 100644 helm/openrag/templates/dashboards/deployment.yaml create mode 100644 helm/openrag/templates/dashboards/service.yaml create mode 100644 helm/openrag/templates/frontend/deployment.yaml create mode 100644 helm/openrag/templates/frontend/hpa.yaml create mode 100644 helm/openrag/templates/frontend/service.yaml create mode 100644 helm/openrag/templates/ingress/ingress.yaml create mode 100644 helm/openrag/templates/langflow/deployment.yaml create mode 100644 helm/openrag/templates/langflow/service.yaml create mode 100644 helm/openrag/templates/secrets/aws-secret.yaml create mode 100644 helm/openrag/templates/secrets/langflow-secret.yaml create mode 100644 helm/openrag/templates/secrets/llm-providers-secret.yaml create mode 100644 helm/openrag/templates/secrets/oauth-secret.yaml create mode 100644 helm/openrag/templates/secrets/opensearch-secret.yaml create mode 100644 helm/openrag/templates/serviceaccount.yaml create mode 100644 helm/openrag/templates/storage/config-pvc.yaml create mode 100644 helm/openrag/templates/storage/documents-pvc.yaml create mode 100644 helm/openrag/templates/storage/keys-pvc.yaml create mode 100644 helm/openrag/templates/storage/langflow-pvc.yaml create mode 100644 helm/openrag/values.yaml diff --git a/helm/openrag/Chart.yaml b/helm/openrag/Chart.yaml new file mode 100644 index 00000000..ac9d0df3 --- /dev/null +++ b/helm/openrag/Chart.yaml @@ -0,0 +1,18 @@ +apiVersion: v2 +name: openrag +description: A Helm chart for deploying OpenRAG - an open-source agentic RAG platform +type: application +version: 0.1.0 +appVersion: "0.1.52" +keywords: + - openrag + - rag + - langflow + - opensearch + - ai + - llm +home: https://github.com/langflow-ai/openrag +sources: + - https://github.com/langflow-ai/openrag +maintainers: + - name: OpenRAG Team diff --git a/helm/openrag/templates/NOTES.txt b/helm/openrag/templates/NOTES.txt new file mode 100644 index 00000000..932754ba --- /dev/null +++ b/helm/openrag/templates/NOTES.txt @@ -0,0 +1,80 @@ +OpenRAG has been deployed successfully! + +{{- if .Values.global.tenant.name }} +Tenant: {{ .Values.global.tenant.name }} +Namespace: {{ include "openrag.namespace" . }} +{{- end }} + +=== Services Deployed === + +{{- if .Values.langflow.enabled }} +Langflow: + - Internal URL: http://{{ include "openrag.fullname" . }}-langflow:{{ .Values.langflow.service.port }} + {{- if and .Values.ingress.enabled .Values.ingress.hosts.langflow.enabled .Values.ingress.hosts.langflow.host }} + - External URL: http{{ if .Values.ingress.tls.enabled }}s{{ end }}://{{ .Values.ingress.hosts.langflow.host }} + {{- end }} +{{- end }} + +{{- if .Values.backend.enabled }} +Backend API: + - Internal URL: http://{{ include "openrag.fullname" . }}-backend:{{ .Values.backend.service.port }} + {{- if and .Values.ingress.enabled .Values.ingress.hosts.backend.host }} + - External URL: http{{ if .Values.ingress.tls.enabled }}s{{ end }}://{{ .Values.ingress.hosts.backend.host }} + {{- end }} +{{- end }} + +{{- if .Values.frontend.enabled }} +Frontend UI: + - Internal URL: http://{{ include "openrag.fullname" . }}-frontend:{{ .Values.frontend.service.port }} + {{- if and .Values.ingress.enabled .Values.ingress.hosts.frontend.host }} + - External URL: http{{ if .Values.ingress.tls.enabled }}s{{ end }}://{{ .Values.ingress.hosts.frontend.host }} + {{- end }} +{{- end }} + +{{- if .Values.dashboards.enabled }} +OpenSearch Dashboards: + - Internal URL: http://{{ include "openrag.fullname" . }}-dashboards:{{ .Values.dashboards.service.port }} + {{- if and .Values.ingress.enabled .Values.ingress.hosts.dashboards.enabled .Values.ingress.hosts.dashboards.host }} + - External URL: http{{ if .Values.ingress.tls.enabled }}s{{ end }}://{{ .Values.ingress.hosts.dashboards.host }} + {{- end }} +{{- end }} + +=== External Dependencies === + +OpenSearch (External SaaS): + - Host: {{ .Values.global.opensearch.host }} + - Port: {{ .Values.global.opensearch.port }} + - Scheme: {{ .Values.global.opensearch.scheme }} + +=== Credentials === + +To retrieve the Langflow superuser credentials: + + kubectl get secret {{ include "openrag.fullname" . }}-langflow -n {{ include "openrag.namespace" . }} -o jsonpath='{.data.superuser}' | base64 -d + kubectl get secret {{ include "openrag.fullname" . }}-langflow -n {{ include "openrag.namespace" . }} -o jsonpath='{.data.superuser-password}' | base64 -d + +=== Quick Start === + +{{- if and .Values.ingress.enabled .Values.ingress.hosts.frontend.host }} +1. Access the OpenRAG UI at: http{{ if .Values.ingress.tls.enabled }}s{{ end }}://{{ .Values.ingress.hosts.frontend.host }} +{{- else }} +1. Port-forward the frontend service: + kubectl port-forward svc/{{ include "openrag.fullname" . }}-frontend {{ .Values.frontend.service.port }}:{{ .Values.frontend.service.port }} -n {{ include "openrag.namespace" . }} + Then access: http://localhost:{{ .Values.frontend.service.port }} +{{- end }} + +2. Upload documents to your knowledge base + +3. Start chatting with your documents using the AI-powered chat interface + +=== Troubleshooting === + +Check pod status: + kubectl get pods -n {{ include "openrag.namespace" . }} -l app.kubernetes.io/instance={{ .Release.Name }} + +Check pod logs: + kubectl logs -n {{ include "openrag.namespace" . }} -l app.kubernetes.io/component=langflow + kubectl logs -n {{ include "openrag.namespace" . }} -l app.kubernetes.io/component=backend + kubectl logs -n {{ include "openrag.namespace" . }} -l app.kubernetes.io/component=frontend + +For more information, visit: https://github.com/langflow-ai/openrag diff --git a/helm/openrag/templates/_helpers.tpl b/helm/openrag/templates/_helpers.tpl new file mode 100644 index 00000000..c0a49b85 --- /dev/null +++ b/helm/openrag/templates/_helpers.tpl @@ -0,0 +1,163 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "openrag.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +If tenant name is provided, prefix with tenant name. +*/}} +{{- define "openrag.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if .Values.global.tenant.name }} +{{- printf "%s-%s" .Values.global.tenant.name $name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s" $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create the namespace name. +Uses tenant namespace if specified, otherwise tenant name, otherwise release namespace. +*/}} +{{- define "openrag.namespace" -}} +{{- if .Values.global.tenant.namespace }} +{{- .Values.global.tenant.namespace }} +{{- else if .Values.global.tenant.name }} +{{- .Values.global.tenant.name }} +{{- else }} +{{- .Release.Namespace }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "openrag.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "openrag.labels" -}} +helm.sh/chart: {{ include "openrag.chart" . }} +{{ include "openrag.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.global.tenant.name }} +openrag.io/tenant: {{ .Values.global.tenant.name }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "openrag.selectorLabels" -}} +app.kubernetes.io/name: {{ include "openrag.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "openrag.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "openrag.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Langflow component labels +*/}} +{{- define "openrag.langflow.labels" -}} +{{ include "openrag.labels" . }} +app.kubernetes.io/component: langflow +{{- end }} + +{{/* +Langflow selector labels +*/}} +{{- define "openrag.langflow.selectorLabels" -}} +{{ include "openrag.selectorLabels" . }} +app.kubernetes.io/component: langflow +{{- end }} + +{{/* +Backend component labels +*/}} +{{- define "openrag.backend.labels" -}} +{{ include "openrag.labels" . }} +app.kubernetes.io/component: backend +{{- end }} + +{{/* +Backend selector labels +*/}} +{{- define "openrag.backend.selectorLabels" -}} +{{ include "openrag.selectorLabels" . }} +app.kubernetes.io/component: backend +{{- end }} + +{{/* +Frontend component labels +*/}} +{{- define "openrag.frontend.labels" -}} +{{ include "openrag.labels" . }} +app.kubernetes.io/component: frontend +{{- end }} + +{{/* +Frontend selector labels +*/}} +{{- define "openrag.frontend.selectorLabels" -}} +{{ include "openrag.selectorLabels" . }} +app.kubernetes.io/component: frontend +{{- end }} + +{{/* +Dashboards component labels +*/}} +{{- define "openrag.dashboards.labels" -}} +{{ include "openrag.labels" . }} +app.kubernetes.io/component: dashboards +{{- end }} + +{{/* +Dashboards selector labels +*/}} +{{- define "openrag.dashboards.selectorLabels" -}} +{{ include "openrag.selectorLabels" . }} +app.kubernetes.io/component: dashboards +{{- end }} + +{{/* +Generate the Langflow service URL +*/}} +{{- define "openrag.langflow.url" -}} +http://{{ include "openrag.fullname" . }}-langflow:{{ .Values.langflow.service.port }} +{{- end }} + +{{/* +Generate the Backend service URL +*/}} +{{- define "openrag.backend.url" -}} +http://{{ include "openrag.fullname" . }}-backend:{{ .Values.backend.service.port }} +{{- end }} + +{{/* +Generate the OpenSearch URL +*/}} +{{- define "openrag.opensearch.url" -}} +{{ .Values.global.opensearch.scheme }}://{{ .Values.global.opensearch.host }}:{{ .Values.global.opensearch.port }} +{{- end }} diff --git a/helm/openrag/templates/backend/deployment.yaml b/helm/openrag/templates/backend/deployment.yaml new file mode 100644 index 00000000..aa6077ba --- /dev/null +++ b/helm/openrag/templates/backend/deployment.yaml @@ -0,0 +1,273 @@ +{{- if .Values.backend.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "openrag.fullname" . }}-backend + namespace: {{ include "openrag.namespace" . }} + labels: + {{- include "openrag.backend.labels" . | nindent 4 }} +spec: + replicas: 1 # Single pod for vertical scaling + strategy: + type: Recreate # Required for RWO PVCs + selector: + matchLabels: + {{- include "openrag.backend.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "openrag.backend.selectorLabels" . | nindent 8 }} + annotations: + checksum/secret-opensearch: {{ include (print $.Template.BasePath "/secrets/opensearch-secret.yaml") . | sha256sum }} + checksum/secret-langflow: {{ include (print $.Template.BasePath "/secrets/langflow-secret.yaml") . | sha256sum }} + checksum/config-flows: {{ include (print $.Template.BasePath "/configmaps/flow-ids-configmap.yaml") . | sha256sum }} + checksum/config-app: {{ include (print $.Template.BasePath "/configmaps/app-config-configmap.yaml") . | sha256sum }} + spec: + serviceAccountName: {{ include "openrag.serviceAccountName" . }} + {{- with .Values.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.langflow.enabled }} + initContainers: + - name: wait-for-langflow + image: busybox:1.36 + command: + - sh + - -c + - | + echo "Waiting for Langflow to be ready..." + until nc -z {{ include "openrag.fullname" . }}-langflow {{ .Values.langflow.service.port }}; do + echo "Langflow not ready, sleeping 5s..." + sleep 5 + done + echo "Langflow is ready!" + {{- end }} + containers: + - name: backend + image: "{{ .Values.backend.image.repository }}:{{ .Values.backend.image.tag | default .Values.global.imageTag }}" + imagePullPolicy: {{ .Values.global.imagePullPolicy }} + {{- with .Values.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http + containerPort: 8000 + protocol: TCP + env: + # OpenSearch connection (external SaaS) + - name: OPENSEARCH_HOST + value: {{ .Values.global.opensearch.host | quote }} + - name: OPENSEARCH_PORT + value: {{ .Values.global.opensearch.port | quote }} + - name: OPENSEARCH_USERNAME + value: {{ .Values.global.opensearch.username | quote }} + {{- if .Values.global.opensearch.password }} + - name: OPENSEARCH_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "openrag.fullname" . }}-opensearch + key: password + {{- end }} + # Langflow connection + - name: LANGFLOW_URL + value: {{ include "openrag.langflow.url" . | quote }} + {{- if .Values.backend.langflowPublicUrl }} + - name: LANGFLOW_PUBLIC_URL + value: {{ .Values.backend.langflowPublicUrl | quote }} + {{- end }} + - name: LANGFLOW_AUTO_LOGIN + value: {{ .Values.langflow.auth.autoLogin | quote }} + - name: LANGFLOW_SUPERUSER + valueFrom: + secretKeyRef: + name: {{ include "openrag.fullname" . }}-langflow + key: superuser + - name: LANGFLOW_SUPERUSER_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "openrag.fullname" . }}-langflow + key: superuser-password + # Flow IDs from ConfigMap + - name: LANGFLOW_CHAT_FLOW_ID + valueFrom: + configMapKeyRef: + name: {{ include "openrag.fullname" . }}-flow-ids + key: chat-flow-id + - name: LANGFLOW_INGEST_FLOW_ID + valueFrom: + configMapKeyRef: + name: {{ include "openrag.fullname" . }}-flow-ids + key: ingest-flow-id + - name: LANGFLOW_URL_INGEST_FLOW_ID + valueFrom: + configMapKeyRef: + name: {{ include "openrag.fullname" . }}-flow-ids + key: url-ingest-flow-id + - name: NUDGES_FLOW_ID + valueFrom: + configMapKeyRef: + name: {{ include "openrag.fullname" . }}-flow-ids + key: nudges-flow-id + # Feature flags + - name: DISABLE_INGEST_WITH_LANGFLOW + value: {{ .Values.backend.features.disableIngestWithLangflow | quote }} + # LLM Provider keys + {{- if .Values.llmProviders.openai.enabled }} + - name: OPENAI_API_KEY + valueFrom: + secretKeyRef: + name: {{ include "openrag.fullname" . }}-llm-providers + key: openai-api-key + {{- end }} + {{- if .Values.llmProviders.anthropic.enabled }} + - name: ANTHROPIC_API_KEY + valueFrom: + secretKeyRef: + name: {{ include "openrag.fullname" . }}-llm-providers + key: anthropic-api-key + {{- end }} + {{- if .Values.llmProviders.watsonx.enabled }} + - name: WATSONX_API_KEY + valueFrom: + secretKeyRef: + name: {{ include "openrag.fullname" . }}-llm-providers + key: watsonx-api-key + - name: WATSONX_ENDPOINT + valueFrom: + secretKeyRef: + name: {{ include "openrag.fullname" . }}-llm-providers + key: watsonx-endpoint + - name: WATSONX_PROJECT_ID + valueFrom: + secretKeyRef: + name: {{ include "openrag.fullname" . }}-llm-providers + key: watsonx-project-id + {{- end }} + {{- if .Values.llmProviders.ollama.enabled }} + - name: OLLAMA_ENDPOINT + value: {{ .Values.llmProviders.ollama.endpoint | quote }} + {{- end }} + # OAuth credentials + {{- if .Values.global.oauth.google.enabled }} + - name: GOOGLE_OAUTH_CLIENT_ID + valueFrom: + secretKeyRef: + name: {{ include "openrag.fullname" . }}-oauth + key: google-client-id + - name: GOOGLE_OAUTH_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: {{ include "openrag.fullname" . }}-oauth + key: google-client-secret + {{- end }} + {{- if .Values.global.oauth.microsoft.enabled }} + - name: MICROSOFT_GRAPH_OAUTH_CLIENT_ID + valueFrom: + secretKeyRef: + name: {{ include "openrag.fullname" . }}-oauth + key: microsoft-client-id + - name: MICROSOFT_GRAPH_OAUTH_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: {{ include "openrag.fullname" . }}-oauth + key: microsoft-client-secret + {{- end }} + # AWS credentials + {{- if .Values.backend.aws.enabled }} + - name: AWS_ACCESS_KEY_ID + valueFrom: + secretKeyRef: + name: {{ include "openrag.fullname" . }}-aws + key: access-key-id + - name: AWS_SECRET_ACCESS_KEY + valueFrom: + secretKeyRef: + name: {{ include "openrag.fullname" . }}-aws + key: secret-access-key + {{- end }} + # Webhook configuration + {{- if .Values.backend.webhook.enabled }} + - name: WEBHOOK_BASE_URL + value: {{ .Values.backend.webhook.baseUrl | quote }} + {{- end }} + volumeMounts: + {{- if .Values.backend.persistence.documents.enabled }} + - name: documents + mountPath: {{ .Values.backend.persistence.documents.mountPath }} + {{- end }} + {{- if .Values.backend.persistence.keys.enabled }} + - name: keys + mountPath: {{ .Values.backend.persistence.keys.mountPath }} + {{- end }} + {{- if .Values.backend.persistence.config.enabled }} + - name: config + mountPath: {{ .Values.backend.persistence.config.mountPath }} + {{- end }} + {{- if .Values.langflow.persistence.enabled }} + - name: flows + mountPath: /app/flows + subPath: {{ .Values.langflow.persistence.flowsSubPath }} + readOnly: true + {{- end }} + resources: + {{- toYaml .Values.backend.resources | nindent 12 }} + {{- if .Values.backend.livenessProbe.enabled }} + livenessProbe: + httpGet: + path: /health + port: http + initialDelaySeconds: {{ .Values.backend.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.backend.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.backend.livenessProbe.timeoutSeconds }} + failureThreshold: {{ .Values.backend.livenessProbe.failureThreshold }} + {{- end }} + {{- if .Values.backend.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: /health + port: http + initialDelaySeconds: {{ .Values.backend.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.backend.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.backend.readinessProbe.timeoutSeconds }} + failureThreshold: {{ .Values.backend.readinessProbe.failureThreshold }} + {{- end }} + volumes: + {{- if .Values.backend.persistence.documents.enabled }} + - name: documents + persistentVolumeClaim: + claimName: {{ include "openrag.fullname" . }}-documents + {{- end }} + {{- if .Values.backend.persistence.keys.enabled }} + - name: keys + persistentVolumeClaim: + claimName: {{ include "openrag.fullname" . }}-keys + {{- end }} + {{- if .Values.backend.persistence.config.enabled }} + - name: config + persistentVolumeClaim: + claimName: {{ include "openrag.fullname" . }}-config + {{- end }} + {{- if .Values.langflow.persistence.enabled }} + - name: flows + persistentVolumeClaim: + claimName: {{ include "openrag.fullname" . }}-langflow + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/helm/openrag/templates/backend/service.yaml b/helm/openrag/templates/backend/service.yaml new file mode 100644 index 00000000..d105de86 --- /dev/null +++ b/helm/openrag/templates/backend/service.yaml @@ -0,0 +1,18 @@ +{{- if .Values.backend.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "openrag.fullname" . }}-backend + namespace: {{ include "openrag.namespace" . }} + labels: + {{- include "openrag.backend.labels" . | nindent 4 }} +spec: + type: {{ .Values.backend.service.type }} + ports: + - port: {{ .Values.backend.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "openrag.backend.selectorLabels" . | nindent 4 }} +{{- end }} diff --git a/helm/openrag/templates/configmaps/app-config-configmap.yaml b/helm/openrag/templates/configmaps/app-config-configmap.yaml new file mode 100644 index 00000000..e04dea4c --- /dev/null +++ b/helm/openrag/templates/configmaps/app-config-configmap.yaml @@ -0,0 +1,39 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "openrag.fullname" . }}-app-config + namespace: {{ include "openrag.namespace" . }} + labels: + {{- include "openrag.labels" . | nindent 4 }} +data: + config.yaml: | + agent: + llm_model: {{ .Values.appConfig.agent.llmModel | quote }} + llm_provider: {{ .Values.appConfig.agent.llmProvider | quote }} + {{- if .Values.appConfig.agent.systemPrompt }} + system_prompt: {{ .Values.appConfig.agent.systemPrompt | quote }} + {{- end }} + edited: false + knowledge: + chunk_overlap: {{ .Values.appConfig.knowledge.chunkOverlap }} + chunk_size: {{ .Values.appConfig.knowledge.chunkSize }} + embedding_model: {{ .Values.appConfig.knowledge.embeddingModel | quote }} + embedding_provider: {{ .Values.appConfig.knowledge.embeddingProvider | quote }} + ocr: {{ .Values.appConfig.knowledge.ocr }} + picture_descriptions: {{ .Values.appConfig.knowledge.pictureDescriptions }} + table_structure: {{ .Values.appConfig.knowledge.tableStructure }} + providers: + anthropic: + configured: {{ .Values.llmProviders.anthropic.enabled }} + ollama: + configured: {{ .Values.llmProviders.ollama.enabled }} + {{- if .Values.llmProviders.ollama.endpoint }} + endpoint: {{ .Values.llmProviders.ollama.endpoint | quote }} + {{- end }} + openai: + configured: {{ .Values.llmProviders.openai.enabled }} + watsonx: + configured: {{ .Values.llmProviders.watsonx.enabled }} + {{- if .Values.llmProviders.watsonx.endpoint }} + endpoint: {{ .Values.llmProviders.watsonx.endpoint | quote }} + {{- end }} diff --git a/helm/openrag/templates/configmaps/flow-ids-configmap.yaml b/helm/openrag/templates/configmaps/flow-ids-configmap.yaml new file mode 100644 index 00000000..4e4dfb9c --- /dev/null +++ b/helm/openrag/templates/configmaps/flow-ids-configmap.yaml @@ -0,0 +1,14 @@ +{{- if .Values.langflow.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "openrag.fullname" . }}-flow-ids + namespace: {{ include "openrag.namespace" . }} + labels: + {{- include "openrag.labels" . | nindent 4 }} +data: + chat-flow-id: {{ .Values.langflow.flows.chatFlowId | quote }} + ingest-flow-id: {{ .Values.langflow.flows.ingestFlowId | quote }} + url-ingest-flow-id: {{ .Values.langflow.flows.urlIngestFlowId | quote }} + nudges-flow-id: {{ .Values.langflow.flows.nudgesFlowId | quote }} +{{- end }} diff --git a/helm/openrag/templates/dashboards/deployment.yaml b/helm/openrag/templates/dashboards/deployment.yaml new file mode 100644 index 00000000..49d87d3a --- /dev/null +++ b/helm/openrag/templates/dashboards/deployment.yaml @@ -0,0 +1,81 @@ +{{- if .Values.dashboards.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "openrag.fullname" . }}-dashboards + namespace: {{ include "openrag.namespace" . }} + labels: + {{- include "openrag.dashboards.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.dashboards.replicaCount }} + selector: + matchLabels: + {{- include "openrag.dashboards.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "openrag.dashboards.selectorLabels" . | nindent 8 }} + annotations: + checksum/secret: {{ include (print $.Template.BasePath "/secrets/opensearch-secret.yaml") . | sha256sum }} + spec: + serviceAccountName: {{ include "openrag.serviceAccountName" . }} + {{- with .Values.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: dashboards + image: "{{ .Values.dashboards.image.repository }}:{{ .Values.dashboards.image.tag }}" + imagePullPolicy: {{ .Values.global.imagePullPolicy }} + ports: + - name: http + containerPort: 5601 + protocol: TCP + env: + # OpenSearch connection (external SaaS) + - name: OPENSEARCH_HOSTS + value: '["{{ include "openrag.opensearch.url" . }}"]' + - name: OPENSEARCH_USERNAME + value: {{ .Values.global.opensearch.username | quote }} + {{- if .Values.global.opensearch.password }} + - name: OPENSEARCH_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "openrag.fullname" . }}-opensearch + key: password + {{- end }} + resources: + {{- toYaml .Values.dashboards.resources | nindent 12 }} + {{- if .Values.dashboards.livenessProbe.enabled }} + livenessProbe: + httpGet: + path: /api/status + port: http + initialDelaySeconds: {{ .Values.dashboards.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.dashboards.livenessProbe.periodSeconds }} + {{- end }} + {{- if .Values.dashboards.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: /api/status + port: http + initialDelaySeconds: {{ .Values.dashboards.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.dashboards.readinessProbe.periodSeconds }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/helm/openrag/templates/dashboards/service.yaml b/helm/openrag/templates/dashboards/service.yaml new file mode 100644 index 00000000..91830518 --- /dev/null +++ b/helm/openrag/templates/dashboards/service.yaml @@ -0,0 +1,18 @@ +{{- if .Values.dashboards.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "openrag.fullname" . }}-dashboards + namespace: {{ include "openrag.namespace" . }} + labels: + {{- include "openrag.dashboards.labels" . | nindent 4 }} +spec: + type: {{ .Values.dashboards.service.type }} + ports: + - port: {{ .Values.dashboards.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "openrag.dashboards.selectorLabels" . | nindent 4 }} +{{- end }} diff --git a/helm/openrag/templates/frontend/deployment.yaml b/helm/openrag/templates/frontend/deployment.yaml new file mode 100644 index 00000000..4c7ec937 --- /dev/null +++ b/helm/openrag/templates/frontend/deployment.yaml @@ -0,0 +1,80 @@ +{{- if .Values.frontend.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "openrag.fullname" . }}-frontend + namespace: {{ include "openrag.namespace" . }} + labels: + {{- include "openrag.frontend.labels" . | nindent 4 }} +spec: + {{- if not .Values.frontend.autoscaling.enabled }} + replicas: {{ .Values.frontend.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "openrag.frontend.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "openrag.frontend.selectorLabels" . | nindent 8 }} + spec: + serviceAccountName: {{ include "openrag.serviceAccountName" . }} + {{- with .Values.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: frontend + image: "{{ .Values.frontend.image.repository }}:{{ .Values.frontend.image.tag | default .Values.global.imageTag }}" + imagePullPolicy: {{ .Values.global.imagePullPolicy }} + {{- with .Values.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http + containerPort: 3000 + protocol: TCP + env: + # Backend connection (uses internal service name) + - name: OPENRAG_BACKEND_HOST + value: "{{ include "openrag.fullname" . }}-backend" + resources: + {{- toYaml .Values.frontend.resources | nindent 12 }} + {{- if .Values.frontend.livenessProbe.enabled }} + livenessProbe: + httpGet: + path: / + port: http + initialDelaySeconds: {{ .Values.frontend.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.frontend.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.frontend.livenessProbe.timeoutSeconds }} + failureThreshold: {{ .Values.frontend.livenessProbe.failureThreshold }} + {{- end }} + {{- if .Values.frontend.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: / + port: http + initialDelaySeconds: {{ .Values.frontend.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.frontend.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.frontend.readinessProbe.timeoutSeconds }} + failureThreshold: {{ .Values.frontend.readinessProbe.failureThreshold }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/helm/openrag/templates/frontend/hpa.yaml b/helm/openrag/templates/frontend/hpa.yaml new file mode 100644 index 00000000..306b0108 --- /dev/null +++ b/helm/openrag/templates/frontend/hpa.yaml @@ -0,0 +1,33 @@ +{{- if and .Values.frontend.enabled .Values.frontend.autoscaling.enabled }} +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "openrag.fullname" . }}-frontend + namespace: {{ include "openrag.namespace" . }} + labels: + {{- include "openrag.frontend.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "openrag.fullname" . }}-frontend + minReplicas: {{ .Values.frontend.autoscaling.minReplicas }} + maxReplicas: {{ .Values.frontend.autoscaling.maxReplicas }} + metrics: + {{- if .Values.frontend.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: {{ .Values.frontend.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.frontend.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: {{ .Values.frontend.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/helm/openrag/templates/frontend/service.yaml b/helm/openrag/templates/frontend/service.yaml new file mode 100644 index 00000000..1a3b7c8c --- /dev/null +++ b/helm/openrag/templates/frontend/service.yaml @@ -0,0 +1,18 @@ +{{- if .Values.frontend.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "openrag.fullname" . }}-frontend + namespace: {{ include "openrag.namespace" . }} + labels: + {{- include "openrag.frontend.labels" . | nindent 4 }} +spec: + type: {{ .Values.frontend.service.type }} + ports: + - port: {{ .Values.frontend.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "openrag.frontend.selectorLabels" . | nindent 4 }} +{{- end }} diff --git a/helm/openrag/templates/ingress/ingress.yaml b/helm/openrag/templates/ingress/ingress.yaml new file mode 100644 index 00000000..5e03e5bd --- /dev/null +++ b/helm/openrag/templates/ingress/ingress.yaml @@ -0,0 +1,104 @@ +{{- if .Values.ingress.enabled }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "openrag.fullname" . }} + namespace: {{ include "openrag.namespace" . }} + labels: + {{- include "openrag.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.ingress.tls.certManager.enabled }} + cert-manager.io/cluster-issuer: {{ .Values.ingress.tls.certManager.issuerRef.name }} + {{- end }} +spec: + {{- if .Values.ingress.className }} + ingressClassName: {{ .Values.ingress.className }} + {{- end }} + {{- if .Values.ingress.tls.enabled }} + tls: + {{- if .Values.ingress.hosts.frontend.host }} + - hosts: + - {{ .Values.ingress.hosts.frontend.host }} + secretName: {{ .Values.ingress.tls.secretName | default (printf "%s-frontend-tls" (include "openrag.fullname" .)) }} + {{- end }} + {{- if .Values.ingress.hosts.backend.host }} + - hosts: + - {{ .Values.ingress.hosts.backend.host }} + secretName: {{ .Values.ingress.tls.secretName | default (printf "%s-backend-tls" (include "openrag.fullname" .)) }} + {{- end }} + {{- if and .Values.ingress.hosts.langflow.enabled .Values.ingress.hosts.langflow.host }} + - hosts: + - {{ .Values.ingress.hosts.langflow.host }} + secretName: {{ .Values.ingress.tls.secretName | default (printf "%s-langflow-tls" (include "openrag.fullname" .)) }} + {{- end }} + {{- if and .Values.dashboards.enabled .Values.ingress.hosts.dashboards.enabled .Values.ingress.hosts.dashboards.host }} + - hosts: + - {{ .Values.ingress.hosts.dashboards.host }} + secretName: {{ .Values.ingress.tls.secretName | default (printf "%s-dashboards-tls" (include "openrag.fullname" .)) }} + {{- end }} + {{- end }} + rules: + {{- if .Values.ingress.hosts.frontend.host }} + # Frontend ingress rule + - host: {{ .Values.ingress.hosts.frontend.host }} + http: + paths: + {{- range .Values.ingress.hosts.frontend.paths }} + - path: {{ .path }} + pathType: {{ .pathType }} + backend: + service: + name: {{ include "openrag.fullname" $ }}-frontend + port: + number: {{ $.Values.frontend.service.port }} + {{- end }} + {{- end }} + {{- if .Values.ingress.hosts.backend.host }} + # Backend API ingress rule + - host: {{ .Values.ingress.hosts.backend.host }} + http: + paths: + {{- range .Values.ingress.hosts.backend.paths }} + - path: {{ .path }} + pathType: {{ .pathType }} + backend: + service: + name: {{ include "openrag.fullname" $ }}-backend + port: + number: {{ $.Values.backend.service.port }} + {{- end }} + {{- end }} + {{- if and .Values.ingress.hosts.langflow.enabled .Values.ingress.hosts.langflow.host }} + # Optional Langflow direct access + - host: {{ .Values.ingress.hosts.langflow.host }} + http: + paths: + {{- range .Values.ingress.hosts.langflow.paths }} + - path: {{ .path }} + pathType: {{ .pathType }} + backend: + service: + name: {{ include "openrag.fullname" $ }}-langflow + port: + number: {{ $.Values.langflow.service.port }} + {{- end }} + {{- end }} + {{- if and .Values.dashboards.enabled .Values.ingress.hosts.dashboards.enabled .Values.ingress.hosts.dashboards.host }} + # Optional Dashboards access + - host: {{ .Values.ingress.hosts.dashboards.host }} + http: + paths: + {{- range .Values.ingress.hosts.dashboards.paths }} + - path: {{ .path }} + pathType: {{ .pathType }} + backend: + service: + name: {{ include "openrag.fullname" $ }}-dashboards + port: + number: {{ $.Values.dashboards.service.port }} + {{- end }} + {{- end }} +{{- end }} diff --git a/helm/openrag/templates/langflow/deployment.yaml b/helm/openrag/templates/langflow/deployment.yaml new file mode 100644 index 00000000..f583f9a1 --- /dev/null +++ b/helm/openrag/templates/langflow/deployment.yaml @@ -0,0 +1,211 @@ +{{- if .Values.langflow.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "openrag.fullname" . }}-langflow + namespace: {{ include "openrag.namespace" . }} + labels: + {{- include "openrag.langflow.labels" . | nindent 4 }} +spec: + replicas: 1 # Always 1 for SQLite-based Langflow + strategy: + type: Recreate # Required for RWO PVC + selector: + matchLabels: + {{- include "openrag.langflow.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "openrag.langflow.selectorLabels" . | nindent 8 }} + annotations: + checksum/secret: {{ include (print $.Template.BasePath "/secrets/langflow-secret.yaml") . | sha256sum }} + checksum/config: {{ include (print $.Template.BasePath "/configmaps/flow-ids-configmap.yaml") . | sha256sum }} + spec: + serviceAccountName: {{ include "openrag.serviceAccountName" . }} + {{- with .Values.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: langflow + image: "{{ .Values.langflow.image.repository }}:{{ .Values.langflow.image.tag | default .Values.global.imageTag }}" + imagePullPolicy: {{ .Values.global.imagePullPolicy }} + {{- with .Values.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http + containerPort: 7860 + protocol: TCP + env: + # Langflow core settings + - name: LANGFLOW_LOAD_FLOWS_PATH + value: {{ .Values.langflow.persistence.mountPath }}/{{ .Values.langflow.persistence.flowsSubPath }} + - name: LANGFLOW_DATABASE_URL + value: "sqlite:///{{ .Values.langflow.persistence.mountPath }}/{{ .Values.langflow.persistence.dbSubPath }}" + - name: LANGFLOW_DEACTIVATE_TRACING + value: {{ .Values.langflow.deactivateTracing | quote }} + - name: LANGFLOW_LOG_LEVEL + value: {{ .Values.langflow.logLevel | quote }} + - name: HIDE_GETTING_STARTED_PROGRESS + value: "true" + # Auth settings + - name: LANGFLOW_AUTO_LOGIN + value: {{ .Values.langflow.auth.autoLogin | quote }} + - name: LANGFLOW_NEW_USER_IS_ACTIVE + value: {{ .Values.langflow.auth.newUserIsActive | quote }} + - name: LANGFLOW_ENABLE_SUPERUSER_CLI + value: {{ .Values.langflow.auth.enableSuperuserCli | quote }} + # Variables to expose to flows + - name: LANGFLOW_VARIABLES_TO_GET_FROM_ENVIRONMENT + value: {{ .Values.langflow.variablesToGetFromEnvironment | quote }} + # Flow context variables (defaults for flow execution) + - name: JWT + value: "None" + - name: OWNER + value: "None" + - name: OWNER_NAME + value: "None" + - name: OWNER_EMAIL + value: "None" + - name: CONNECTOR_TYPE + value: "system" + - name: CONNECTOR_TYPE_URL + value: "url" + - name: OPENRAG-QUERY-FILTER + value: "{}" + - name: FILENAME + value: "None" + - name: MIMETYPE + value: "None" + - name: FILESIZE + value: "0" + - name: SELECTED_EMBEDDING_MODEL + value: "" + # Secrets from langflow secret + - name: LANGFLOW_SECRET_KEY + valueFrom: + secretKeyRef: + name: {{ include "openrag.fullname" . }}-langflow + key: secret-key + - name: LANGFLOW_SUPERUSER + valueFrom: + secretKeyRef: + name: {{ include "openrag.fullname" . }}-langflow + key: superuser + - name: LANGFLOW_SUPERUSER_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "openrag.fullname" . }}-langflow + key: superuser-password + # OpenSearch password (for flows) + {{- if .Values.global.opensearch.password }} + - name: OPENSEARCH_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "openrag.fullname" . }}-opensearch + key: password + {{- end }} + # LLM Provider keys + {{- if .Values.llmProviders.openai.enabled }} + - name: OPENAI_API_KEY + valueFrom: + secretKeyRef: + name: {{ include "openrag.fullname" . }}-llm-providers + key: openai-api-key + {{- else }} + - name: OPENAI_API_KEY + value: "None" + {{- end }} + {{- if .Values.llmProviders.anthropic.enabled }} + - name: ANTHROPIC_API_KEY + valueFrom: + secretKeyRef: + name: {{ include "openrag.fullname" . }}-llm-providers + key: anthropic-api-key + {{- else }} + - name: ANTHROPIC_API_KEY + value: "None" + {{- end }} + {{- if .Values.llmProviders.watsonx.enabled }} + - name: WATSONX_API_KEY + valueFrom: + secretKeyRef: + name: {{ include "openrag.fullname" . }}-llm-providers + key: watsonx-api-key + - name: WATSONX_ENDPOINT + valueFrom: + secretKeyRef: + name: {{ include "openrag.fullname" . }}-llm-providers + key: watsonx-endpoint + - name: WATSONX_PROJECT_ID + valueFrom: + secretKeyRef: + name: {{ include "openrag.fullname" . }}-llm-providers + key: watsonx-project-id + {{- else }} + - name: WATSONX_API_KEY + value: "None" + - name: WATSONX_ENDPOINT + value: "None" + - name: WATSONX_PROJECT_ID + value: "None" + {{- end }} + {{- if .Values.llmProviders.ollama.enabled }} + - name: OLLAMA_BASE_URL + value: {{ .Values.llmProviders.ollama.endpoint | quote }} + {{- else }} + - name: OLLAMA_BASE_URL + value: "None" + {{- end }} + volumeMounts: + - name: langflow-data + mountPath: {{ .Values.langflow.persistence.mountPath }} + resources: + {{- toYaml .Values.langflow.resources | nindent 12 }} + {{- if .Values.langflow.livenessProbe.enabled }} + livenessProbe: + httpGet: + path: /health + port: http + initialDelaySeconds: {{ .Values.langflow.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.langflow.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.langflow.livenessProbe.timeoutSeconds }} + failureThreshold: {{ .Values.langflow.livenessProbe.failureThreshold }} + {{- end }} + {{- if .Values.langflow.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: /health + port: http + initialDelaySeconds: {{ .Values.langflow.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.langflow.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.langflow.readinessProbe.timeoutSeconds }} + failureThreshold: {{ .Values.langflow.readinessProbe.failureThreshold }} + {{- end }} + volumes: + - name: langflow-data + {{- if .Values.langflow.persistence.enabled }} + persistentVolumeClaim: + claimName: {{ include "openrag.fullname" . }}-langflow + {{- else }} + emptyDir: {} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/helm/openrag/templates/langflow/service.yaml b/helm/openrag/templates/langflow/service.yaml new file mode 100644 index 00000000..ae9c98e1 --- /dev/null +++ b/helm/openrag/templates/langflow/service.yaml @@ -0,0 +1,18 @@ +{{- if .Values.langflow.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "openrag.fullname" . }}-langflow + namespace: {{ include "openrag.namespace" . }} + labels: + {{- include "openrag.langflow.labels" . | nindent 4 }} +spec: + type: {{ .Values.langflow.service.type }} + ports: + - port: {{ .Values.langflow.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "openrag.langflow.selectorLabels" . | nindent 4 }} +{{- end }} diff --git a/helm/openrag/templates/secrets/aws-secret.yaml b/helm/openrag/templates/secrets/aws-secret.yaml new file mode 100644 index 00000000..b20ad07a --- /dev/null +++ b/helm/openrag/templates/secrets/aws-secret.yaml @@ -0,0 +1,13 @@ +{{- if .Values.backend.aws.enabled }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "openrag.fullname" . }}-aws + namespace: {{ include "openrag.namespace" . }} + labels: + {{- include "openrag.labels" . | nindent 4 }} +type: Opaque +stringData: + access-key-id: {{ .Values.backend.aws.accessKeyId | quote }} + secret-access-key: {{ .Values.backend.aws.secretAccessKey | quote }} +{{- end }} diff --git a/helm/openrag/templates/secrets/langflow-secret.yaml b/helm/openrag/templates/secrets/langflow-secret.yaml new file mode 100644 index 00000000..e43e07b1 --- /dev/null +++ b/helm/openrag/templates/secrets/langflow-secret.yaml @@ -0,0 +1,14 @@ +{{- if .Values.langflow.enabled }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "openrag.fullname" . }}-langflow + namespace: {{ include "openrag.namespace" . }} + labels: + {{- include "openrag.labels" . | nindent 4 }} +type: Opaque +stringData: + secret-key: {{ .Values.langflow.auth.secretKey | default (randAlphaNum 32) | quote }} + superuser: {{ .Values.langflow.auth.superuser | quote }} + superuser-password: {{ .Values.langflow.auth.superuserPassword | default (randAlphaNum 16) | quote }} +{{- end }} diff --git a/helm/openrag/templates/secrets/llm-providers-secret.yaml b/helm/openrag/templates/secrets/llm-providers-secret.yaml new file mode 100644 index 00000000..9c394c2a --- /dev/null +++ b/helm/openrag/templates/secrets/llm-providers-secret.yaml @@ -0,0 +1,22 @@ +{{- if or .Values.llmProviders.openai.enabled .Values.llmProviders.anthropic.enabled .Values.llmProviders.watsonx.enabled }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "openrag.fullname" . }}-llm-providers + namespace: {{ include "openrag.namespace" . }} + labels: + {{- include "openrag.labels" . | nindent 4 }} +type: Opaque +stringData: + {{- if .Values.llmProviders.openai.enabled }} + openai-api-key: {{ .Values.llmProviders.openai.apiKey | quote }} + {{- end }} + {{- if .Values.llmProviders.anthropic.enabled }} + anthropic-api-key: {{ .Values.llmProviders.anthropic.apiKey | quote }} + {{- end }} + {{- if .Values.llmProviders.watsonx.enabled }} + watsonx-api-key: {{ .Values.llmProviders.watsonx.apiKey | quote }} + watsonx-endpoint: {{ .Values.llmProviders.watsonx.endpoint | quote }} + watsonx-project-id: {{ .Values.llmProviders.watsonx.projectId | quote }} + {{- end }} +{{- end }} diff --git a/helm/openrag/templates/secrets/oauth-secret.yaml b/helm/openrag/templates/secrets/oauth-secret.yaml new file mode 100644 index 00000000..4742c42b --- /dev/null +++ b/helm/openrag/templates/secrets/oauth-secret.yaml @@ -0,0 +1,19 @@ +{{- if or .Values.global.oauth.google.enabled .Values.global.oauth.microsoft.enabled }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "openrag.fullname" . }}-oauth + namespace: {{ include "openrag.namespace" . }} + labels: + {{- include "openrag.labels" . | nindent 4 }} +type: Opaque +stringData: + {{- if .Values.global.oauth.google.enabled }} + google-client-id: {{ .Values.global.oauth.google.clientId | quote }} + google-client-secret: {{ .Values.global.oauth.google.clientSecret | quote }} + {{- end }} + {{- if .Values.global.oauth.microsoft.enabled }} + microsoft-client-id: {{ .Values.global.oauth.microsoft.clientId | quote }} + microsoft-client-secret: {{ .Values.global.oauth.microsoft.clientSecret | quote }} + {{- end }} +{{- end }} diff --git a/helm/openrag/templates/secrets/opensearch-secret.yaml b/helm/openrag/templates/secrets/opensearch-secret.yaml new file mode 100644 index 00000000..07909041 --- /dev/null +++ b/helm/openrag/templates/secrets/opensearch-secret.yaml @@ -0,0 +1,13 @@ +{{- if .Values.global.opensearch.password }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "openrag.fullname" . }}-opensearch + namespace: {{ include "openrag.namespace" . }} + labels: + {{- include "openrag.labels" . | nindent 4 }} +type: Opaque +stringData: + password: {{ .Values.global.opensearch.password | quote }} + username: {{ .Values.global.opensearch.username | quote }} +{{- end }} diff --git a/helm/openrag/templates/serviceaccount.yaml b/helm/openrag/templates/serviceaccount.yaml new file mode 100644 index 00000000..aa4f377b --- /dev/null +++ b/helm/openrag/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "openrag.serviceAccountName" . }} + namespace: {{ include "openrag.namespace" . }} + labels: + {{- include "openrag.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/openrag/templates/storage/config-pvc.yaml b/helm/openrag/templates/storage/config-pvc.yaml new file mode 100644 index 00000000..d5ced07f --- /dev/null +++ b/helm/openrag/templates/storage/config-pvc.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.backend.enabled .Values.backend.persistence.config.enabled }} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "openrag.fullname" . }}-config + namespace: {{ include "openrag.namespace" . }} + labels: + {{- include "openrag.backend.labels" . | nindent 4 }} +spec: + accessModes: + - {{ .Values.backend.persistence.config.accessMode }} + {{- if .Values.backend.persistence.config.storageClass }} + storageClassName: {{ .Values.backend.persistence.config.storageClass | quote }} + {{- end }} + resources: + requests: + storage: {{ .Values.backend.persistence.config.size }} +{{- end }} diff --git a/helm/openrag/templates/storage/documents-pvc.yaml b/helm/openrag/templates/storage/documents-pvc.yaml new file mode 100644 index 00000000..03ee3401 --- /dev/null +++ b/helm/openrag/templates/storage/documents-pvc.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.backend.enabled .Values.backend.persistence.documents.enabled }} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "openrag.fullname" . }}-documents + namespace: {{ include "openrag.namespace" . }} + labels: + {{- include "openrag.backend.labels" . | nindent 4 }} +spec: + accessModes: + - {{ .Values.backend.persistence.documents.accessMode }} + {{- if .Values.backend.persistence.documents.storageClass }} + storageClassName: {{ .Values.backend.persistence.documents.storageClass | quote }} + {{- end }} + resources: + requests: + storage: {{ .Values.backend.persistence.documents.size }} +{{- end }} diff --git a/helm/openrag/templates/storage/keys-pvc.yaml b/helm/openrag/templates/storage/keys-pvc.yaml new file mode 100644 index 00000000..6d2acd4c --- /dev/null +++ b/helm/openrag/templates/storage/keys-pvc.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.backend.enabled .Values.backend.persistence.keys.enabled }} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "openrag.fullname" . }}-keys + namespace: {{ include "openrag.namespace" . }} + labels: + {{- include "openrag.backend.labels" . | nindent 4 }} +spec: + accessModes: + - {{ .Values.backend.persistence.keys.accessMode }} + {{- if .Values.backend.persistence.keys.storageClass }} + storageClassName: {{ .Values.backend.persistence.keys.storageClass | quote }} + {{- end }} + resources: + requests: + storage: {{ .Values.backend.persistence.keys.size }} +{{- end }} diff --git a/helm/openrag/templates/storage/langflow-pvc.yaml b/helm/openrag/templates/storage/langflow-pvc.yaml new file mode 100644 index 00000000..b1a7e21c --- /dev/null +++ b/helm/openrag/templates/storage/langflow-pvc.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.langflow.enabled .Values.langflow.persistence.enabled }} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "openrag.fullname" . }}-langflow + namespace: {{ include "openrag.namespace" . }} + labels: + {{- include "openrag.langflow.labels" . | nindent 4 }} +spec: + accessModes: + - {{ .Values.langflow.persistence.accessMode }} + {{- if .Values.langflow.persistence.storageClass }} + storageClassName: {{ .Values.langflow.persistence.storageClass | quote }} + {{- end }} + resources: + requests: + storage: {{ .Values.langflow.persistence.size }} +{{- end }} diff --git a/helm/openrag/values.yaml b/helm/openrag/values.yaml new file mode 100644 index 00000000..c589ea74 --- /dev/null +++ b/helm/openrag/values.yaml @@ -0,0 +1,407 @@ +# OpenRAG Helm Chart Values +# This chart deploys OpenRAG with external OpenSearch SaaS connection + +# Override names +nameOverride: "" +fullnameOverride: "" + +# Global settings +global: + # Tenant identification - used for resource naming and namespace + tenant: + name: "" # Required for multi-tenant: tenant identifier (e.g., "acme") + namespace: "" # Optional: override namespace (defaults to tenant name or release namespace) + + # Image settings + imageRegistry: "langflowai" + imagePullPolicy: IfNotPresent + imageTag: "latest" # Override with specific version in production + imagePullSecrets: [] + + # External OpenSearch SaaS connection (OpenSearch is NOT deployed by this chart) + opensearch: + host: "" # Required: OpenSearch SaaS endpoint (e.g., "my-cluster.us-east-1.es.amazonaws.com") + port: 443 # Default HTTPS port for managed OpenSearch + scheme: "https" # https for production SaaS + username: "admin" # OpenSearch username + password: "" # OpenSearch password (stored in secret) + + # Shared OAuth credentials (same across all tenants) + oauth: + google: + enabled: false + clientId: "" # Google OAuth client ID + clientSecret: "" # Google OAuth client secret + microsoft: + enabled: false + clientId: "" # Microsoft Graph OAuth client ID + clientSecret: "" # Microsoft Graph OAuth client secret + +# ============================================================================ +# Langflow Configuration +# ============================================================================ +langflow: + enabled: true + + image: + repository: langflowai/openrag-langflow + tag: "" # Uses global.imageTag if empty + + # Single pod - vertical scaling only (SQLite requires single writer) + replicaCount: 1 + + # Resource requests/limits for vertical scaling + resources: + requests: + cpu: "500m" + memory: "1Gi" + limits: + cpu: "4" + memory: "8Gi" + + # Persistence for SQLite DB and flows + persistence: + enabled: true + storageClass: "" # Empty uses cluster default + accessMode: ReadWriteOnce + size: 10Gi + mountPath: /app/data + flowsSubPath: flows + dbSubPath: langflow.db + + # Flow configuration (UUIDs for Langflow workflows) + flows: + chatFlowId: "1098eea1-6649-4e1d-aed1-b77249fb8dd0" + ingestFlowId: "5488df7c-b93f-4f87-a446-b67028bc0813" + urlIngestFlowId: "72c3d17c-2dac-4a73-b48a-6518473d7830" + nudgesFlowId: "ebc01d31-1976-46ce-a385-b0240327226c" + loadPath: /app/flows + + # Authentication settings + auth: + autoLogin: false + superuser: "admin" # Langflow superuser username + superuserPassword: "" # Langflow superuser password (stored in secret) + secretKey: "" # Langflow secret key for JWT (stored in secret) + newUserIsActive: false + enableSuperuserCli: false + + # Runtime settings + deactivateTracing: true + logLevel: "INFO" # DEBUG, INFO, WARNING, ERROR + + # Variables to expose to flows + variablesToGetFromEnvironment: "JWT,OPENRAG-QUERY-FILTER,OPENSEARCH_PASSWORD,OWNER,OWNER_NAME,OWNER_EMAIL,CONNECTOR_TYPE,FILENAME,MIMETYPE,FILESIZE,SELECTED_EMBEDDING_MODEL,OPENAI_API_KEY,ANTHROPIC_API_KEY,WATSONX_API_KEY,WATSONX_ENDPOINT,WATSONX_PROJECT_ID,OLLAMA_BASE_URL" + + # Probes + livenessProbe: + enabled: true + initialDelaySeconds: 60 + periodSeconds: 30 + timeoutSeconds: 10 + failureThreshold: 3 + readinessProbe: + enabled: true + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 3 + + # Service configuration + service: + type: ClusterIP + port: 7860 + +# ============================================================================ +# OpenRAG Backend Configuration +# ============================================================================ +backend: + enabled: true + + image: + repository: langflowai/openrag-backend + tag: "" # Uses global.imageTag if empty + + # Single pod for vertical scaling + replicaCount: 1 + + # Resource requests/limits + resources: + requests: + cpu: "500m" + memory: "2Gi" + limits: + cpu: "4" + memory: "16Gi" + + # Persistence for documents, keys, and config + persistence: + documents: + enabled: true + storageClass: "" + accessMode: ReadWriteOnce + size: 50Gi + mountPath: /app/openrag-documents + keys: + enabled: true + storageClass: "" + accessMode: ReadWriteOnce + size: 1Gi + mountPath: /app/keys + config: + enabled: true + storageClass: "" + accessMode: ReadWriteOnce + size: 1Gi + mountPath: /app/config + + # Feature flags + features: + disableIngestWithLangflow: false # Set true to use traditional processor instead of Langflow + + # Langflow public URL (for UI links to Langflow) + langflowPublicUrl: "" # e.g., "https://langflow.example.com" + + # Webhook configuration for continuous ingestion + webhook: + enabled: false + baseUrl: "" # DNS routable URL for webhooks (e.g., ngrok URL) + + # AWS credentials for S3 integration + aws: + enabled: false + accessKeyId: "" + secretAccessKey: "" + + # Probes + livenessProbe: + enabled: true + initialDelaySeconds: 30 + periodSeconds: 30 + timeoutSeconds: 10 + failureThreshold: 3 + readinessProbe: + enabled: true + initialDelaySeconds: 15 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 3 + + # Service configuration + service: + type: ClusterIP + port: 8000 + +# ============================================================================ +# OpenRAG Frontend Configuration +# ============================================================================ +frontend: + enabled: true + + image: + repository: langflowai/openrag-frontend + tag: "" # Uses global.imageTag if empty + + # Can be multiple replicas (stateless) + replicaCount: 2 + + # Resource requests/limits + resources: + requests: + cpu: "100m" + memory: "256Mi" + limits: + cpu: "1" + memory: "1Gi" + + # Horizontal Pod Autoscaler + autoscaling: + enabled: false + minReplicas: 2 + maxReplicas: 10 + targetCPUUtilizationPercentage: 70 + targetMemoryUtilizationPercentage: 80 + + # Probes + livenessProbe: + enabled: true + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 3 + readinessProbe: + enabled: true + initialDelaySeconds: 10 + periodSeconds: 5 + timeoutSeconds: 3 + failureThreshold: 3 + + # Service configuration + service: + type: ClusterIP + port: 3000 + +# ============================================================================ +# OpenSearch Dashboards Configuration (Optional) +# ============================================================================ +dashboards: + enabled: false # Enable only if dashboards available in OS SaaS + + image: + repository: opensearchproject/opensearch-dashboards + tag: "3.0.0" + + replicaCount: 1 + + # Resource requests/limits + resources: + requests: + cpu: "100m" + memory: "512Mi" + limits: + cpu: "1" + memory: "2Gi" + + # Probes + livenessProbe: + enabled: true + initialDelaySeconds: 60 + periodSeconds: 30 + readinessProbe: + enabled: true + initialDelaySeconds: 30 + periodSeconds: 10 + + # Service configuration + service: + type: ClusterIP + port: 5601 + +# ============================================================================ +# Ingress Configuration +# ============================================================================ +ingress: + enabled: true + className: "nginx" # nginx, alb, traefik, etc. + + # Annotations for ingress controller + annotations: {} + # For nginx: + # nginx.ingress.kubernetes.io/proxy-body-size: "100m" + # nginx.ingress.kubernetes.io/proxy-read-timeout: "300" + # For AWS ALB: + # alb.ingress.kubernetes.io/scheme: internet-facing + # alb.ingress.kubernetes.io/target-type: ip + + # Host configuration + hosts: + frontend: + host: "" # e.g., "openrag.example.com" + paths: + - path: / + pathType: Prefix + backend: + host: "" # e.g., "api.openrag.example.com" + paths: + - path: / + pathType: Prefix + langflow: + enabled: false # Optional: expose Langflow directly + host: "" # e.g., "langflow.openrag.example.com" + paths: + - path: / + pathType: Prefix + dashboards: + enabled: false # Only if dashboards.enabled is true + host: "" + paths: + - path: / + pathType: Prefix + + # TLS configuration + tls: + enabled: false + # Use existing secret: + # secretName: "openrag-tls" + + # Or use cert-manager: + certManager: + enabled: false + issuerRef: + name: "letsencrypt-prod" + kind: "ClusterIssuer" + +# ============================================================================ +# LLM Provider API Keys +# ============================================================================ +llmProviders: + openai: + enabled: false + apiKey: "" # OpenAI API key (stored in secret) + anthropic: + enabled: false + apiKey: "" # Anthropic API key (stored in secret) + watsonx: + enabled: false + apiKey: "" # WatsonX API key (stored in secret) + endpoint: "https://us-south.ml.cloud.ibm.com" + projectId: "" # WatsonX project ID + ollama: + enabled: false + endpoint: "" # Ollama endpoint URL (e.g., "http://ollama:11434") + +# ============================================================================ +# Application Config (config.yaml contents) +# ============================================================================ +appConfig: + agent: + llmModel: "claude-sonnet-4-5-20250929" + llmProvider: "anthropic" + # System prompt can be customized here + systemPrompt: "" # Leave empty to use default + knowledge: + chunkOverlap: 200 + chunkSize: 1000 + embeddingModel: "text-embedding-3-large" + embeddingProvider: "openai" + ocr: false + pictureDescriptions: false + tableStructure: true + +# ============================================================================ +# Service Account +# ============================================================================ +serviceAccount: + create: true + name: "" + annotations: {} + +# ============================================================================ +# Pod Security +# ============================================================================ +podSecurityContext: + fsGroup: 1000 + runAsNonRoot: true + +securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: false + runAsUser: 1000 + runAsGroup: 1000 + +# ============================================================================ +# Node Placement +# ============================================================================ +nodeSelector: {} + +tolerations: [] + +affinity: {} + +# ============================================================================ +# Pod Disruption Budgets +# ============================================================================ +podDisruptionBudget: + enabled: false + minAvailable: 1 + # maxUnavailable: 1 From 6119c882e9903b30cd42c208f095ff5e1fc132a1 Mon Sep 17 00:00:00 2001 From: April M <36110273+aimurphy@users.noreply.github.com> Date: Wed, 7 Jan 2026 05:47:28 -0800 Subject: [PATCH 02/21] add algolia block --- docs/docusaurus.config.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index 839ca12f..ab2920e8 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -121,6 +121,15 @@ const config = { }, ], }, + algolia: { + appId: "SMEA51Q5OL", + // public key, safe to commit + apiKey: "b2ec302e9880e8979ad6a68f0c36271e", + indexName: "openrag", + contextualSearch: true, + searchParameters: {}, + searchPagePath: "search", + }, prism: { theme: prismThemes.github, darkTheme: prismThemes.dracula, From cdec80288e624b6800f4acd7dc5cf809636b57a3 Mon Sep 17 00:00:00 2001 From: Steven Harris Date: Sun, 11 Jan 2026 14:06:19 -0800 Subject: [PATCH 03/21] Updated GPU resource reservations to docker-compose Original version was failing on Ubuntu EC2 instance with GPU - error message was: 'validating /home/ubuntu/.openrag/tui/docker-compose.gpu.yml: services.openrag-backend Additional property gpus is not allowed Command exited with status 15 --- docker-compose.gpu.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docker-compose.gpu.yml b/docker-compose.gpu.yml index 4496c4ac..b849cd3b 100644 --- a/docker-compose.gpu.yml +++ b/docker-compose.gpu.yml @@ -3,5 +3,10 @@ services: environment: - NVIDIA_DRIVER_CAPABILITIES=compute,utility - NVIDIA_VISIBLE_DEVICES=all - gpus: all - + deploy: + resources: + reservations: + devices: + - driver: nvidia + count: all + capabilities: [gpu] From f81d0224b303dc7642c2476463b4daa37aa83d33 Mon Sep 17 00:00:00 2001 From: phact Date: Tue, 13 Jan 2026 09:33:51 -0500 Subject: [PATCH 04/21] use U,z for opensearch data --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 79826b3a..c5f809c5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -29,7 +29,7 @@ services: - "9200:9200" - "9600:9600" volumes: - - ${OPENSEARCH_DATA_PATH:-./opensearch-data}:/usr/share/opensearch/data:Z + - ${OPENSEARCH_DATA_PATH:-./opensearch-data}:/usr/share/opensearch/data:U,z dashboards: image: opensearchproject/opensearch-dashboards:3.0.0 From b9e65ed4b99a819a964129fd615adc271eb8fb52 Mon Sep 17 00:00:00 2001 From: phact Date: Tue, 13 Jan 2026 12:11:10 -0500 Subject: [PATCH 05/21] new env var to override docling serve host --- src/api/docling.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/api/docling.py b/src/api/docling.py index 22b709ef..2f9adcbd 100644 --- a/src/api/docling.py +++ b/src/api/docling.py @@ -1,5 +1,6 @@ """Docling service proxy endpoints.""" +import os import socket import struct from pathlib import Path @@ -73,9 +74,15 @@ def determine_docling_host() -> str: return "localhost" -# Detect the host IP once at startup -HOST_IP = determine_docling_host() -DOCLING_SERVICE_URL = f"http://{HOST_IP}:5001" +# Use explicit URL if provided, otherwise auto-detect host +_docling_url_override = os.getenv("DOCLING_SERVE_URL") +if _docling_url_override: + DOCLING_SERVICE_URL = _docling_url_override.rstrip("/") + HOST_IP = _docling_url_override # For display in health responses + logger.info("Using DOCLING_SERVE_URL override: %s", DOCLING_SERVICE_URL) +else: + HOST_IP = determine_docling_host() + DOCLING_SERVICE_URL = f"http://{HOST_IP}:5001" async def health(request: Request) -> JSONResponse: From bb63309d1cb43baff7c4730feae1ce112a05e801 Mon Sep 17 00:00:00 2001 From: April M <36110273+aimurphy@users.noreply.github.com> Date: Tue, 13 Jan 2026 09:18:08 -0800 Subject: [PATCH 06/21] issue 762 and 765 --- docs/docs/_partial-prereq-common.mdx | 4 +++- docs/docs/get-started/docker.mdx | 33 ++++++++++++++++++---------- docs/docs/support/troubleshoot.mdx | 27 +++++++++++++++++++++++ 3 files changed, 52 insertions(+), 12 deletions(-) diff --git a/docs/docs/_partial-prereq-common.mdx b/docs/docs/_partial-prereq-common.mdx index 4682d8cc..621273c7 100644 --- a/docs/docs/_partial-prereq-common.mdx +++ b/docs/docs/_partial-prereq-common.mdx @@ -15,4 +15,6 @@ If a provider offers only one type, you must select two providers. ::: -* Optional: Install GPU support with an NVIDIA GPU, [CUDA](https://docs.nvidia.com/cuda/) support, and compatible NVIDIA drivers on the OpenRAG host machine. If you don't have GPU capabilities, OpenRAG provides an alternate CPU-only deployment. \ No newline at end of file +* Optional: Install GPU support with an NVIDIA GPU, [CUDA](https://docs.nvidia.com/cuda/) support, and compatible NVIDIA drivers on the OpenRAG host machine. +If you don't have GPU capabilities, OpenRAG provides an alternate CPU-only deployment that is suitable for most use cases. +The default CPU-only deployment doesn't prevent you from using GPU acceleration in external services, such as Ollama servers. \ No newline at end of file diff --git a/docs/docs/get-started/docker.mdx b/docs/docs/get-started/docker.mdx index 811d3388..2f12d353 100644 --- a/docs/docs/get-started/docker.mdx +++ b/docs/docs/get-started/docker.mdx @@ -116,17 +116,7 @@ The following variables are required or recommended: 3. Deploy the OpenRAG containers locally using the appropriate Docker Compose configuration for your environment: - * **GPU-accelerated deployment**: If your host machine has an NVIDIA GPU with CUDA support and compatible NVIDIA drivers, use the base `docker-compose.yml` file with the `docker-compose.gpu.yml` override. - - ```bash title="Docker" - docker compose -f docker-compose.yml -f docker-compose.gpu.yml up -d - ``` - - ```bash title="Podman" - podman compose -f docker-compose.yml -f docker-compose.gpu.yml up -d - ``` - - * **CPU-only deployment** (default): If your host machine doesn't have NVIDIA GPU support, use the base `docker-compose.yml` file. + * **CPU-only deployment** (default, recommended): If your host machine doesn't have NVIDIA GPU support, use the base `docker-compose.yml` file. ```bash title="Docker" docker compose up -d @@ -136,6 +126,27 @@ The following variables are required or recommended: podman compose up -d ``` + * **GPU-accelerated deployment**: If your host machine has an NVIDIA GPU with CUDA support and compatible NVIDIA drivers, use the base `docker-compose.yml` file with the `docker-compose.gpu.yml` override: + + ```bash title="Docker" + docker compose -f docker-compose.yml -f docker-compose.gpu.yml up -d + ``` + + ```bash title="Podman" + podman compose -f docker-compose.yml -f docker-compose.gpu.yml up -d + ``` + + tip::: + GPU acceleration isn't required for most use cases. + OpenRAG's CPU-only deployment doesn't prevent you from using GPU acceleration in external services, such as Ollama servers. + + GPU acceleration is required only for specific use cases, typically involving customization of the ingestion flows or ingestion logic. + For example, writing alternate ingest logic in OpenRAG that uses GPUs directly in the container, or customizing the ingestion flows to use Langflow's Docling component with GPU acceleration instead of the `docling serve` service. + + If you are deploying OpenRAG on an Amazon EC2 instance with GPU acceleration enabled, you must edit the `docker-compose.gpu.yml` file before deploying the OpenRAG containers. + For more information, see [Some images failed to pull on Amazon EC2 with GPU support](/support/troubleshoot#some-images-failed-to-pull-on-amazon-ec2-with-gpu-support). + ::: + 4. Wait for the OpenRAG containers to start, and then confirm that all containers are running: ```bash title="Docker" diff --git a/docs/docs/support/troubleshoot.mdx b/docs/docs/support/troubleshoot.mdx index f4d69e6e..fa1cdaa4 100644 --- a/docs/docs/support/troubleshoot.mdx +++ b/docs/docs/support/troubleshoot.mdx @@ -35,6 +35,33 @@ open "/Applications/Python VERSION/Install Certificates.command" Replace `VERSION` with your installed Python version, such as `3.13`. +### Some images failed to pull on Amazon EC2 with GPU support {#some-images-failed-to-pull-on-amazon-ec2-with-gpu-support} + +When installing OpenRAG on an Amazon EC2 instance with GPU acceleration enabled, some Docker images might fail to pull. + +To resolve this issue, do the following: + +1. [Stop the OpenRAG containers](/manage-services#stop-and-start-containers). + +2. In your `~/.openrag` directory, edit the `docker-compose.gpu.yml` file as follows: + + ```yaml + services: + openrag-backend: + environment: + - NVIDIA_DRIVER_CAPABILITIES=compute,utility + - NVIDIA_VISIBLE_DEVICES=all + deploy: + resources: + reservations: + devices: + - driver: nvidia + count: all + capabilities: [gpu] + ``` + +3. [Restart the OpenRAG containers](/manage-services#stop-and-start-containers). + ### Application onboarding gets stuck on Google Chrome If the OpenRAG onboarding process gets stuck when using Google Chrome, try clearing your browser's cache. From ebaa1f1a4eecaa45d77c0a6a99177b52175b97fe Mon Sep 17 00:00:00 2001 From: April M <36110273+aimurphy@users.noreply.github.com> Date: Tue, 13 Jan 2026 09:20:39 -0800 Subject: [PATCH 07/21] punctuation --- docs/docs/get-started/docker.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/get-started/docker.mdx b/docs/docs/get-started/docker.mdx index 2f12d353..acd4a971 100644 --- a/docs/docs/get-started/docker.mdx +++ b/docs/docs/get-started/docker.mdx @@ -116,7 +116,7 @@ The following variables are required or recommended: 3. Deploy the OpenRAG containers locally using the appropriate Docker Compose configuration for your environment: - * **CPU-only deployment** (default, recommended): If your host machine doesn't have NVIDIA GPU support, use the base `docker-compose.yml` file. + * **CPU-only deployment** (default, recommended): If your host machine doesn't have NVIDIA GPU support, use the base `docker-compose.yml` file: ```bash title="Docker" docker compose up -d From 42df43d21ad4fd0f0bd7a98a1391e77a00117082 Mon Sep 17 00:00:00 2001 From: April M <36110273+aimurphy@users.noreply.github.com> Date: Tue, 13 Jan 2026 09:24:52 -0800 Subject: [PATCH 08/21] gpu mode tip partial --- docs/docs/_partial-gpu-mode-tip.mdx | 8 ++++++++ docs/docs/get-started/docker.mdx | 12 +++--------- docs/docs/get-started/tui.mdx | 6 ++++++ 3 files changed, 17 insertions(+), 9 deletions(-) create mode 100644 docs/docs/_partial-gpu-mode-tip.mdx diff --git a/docs/docs/_partial-gpu-mode-tip.mdx b/docs/docs/_partial-gpu-mode-tip.mdx new file mode 100644 index 00000000..6a828ef8 --- /dev/null +++ b/docs/docs/_partial-gpu-mode-tip.mdx @@ -0,0 +1,8 @@ +GPU acceleration isn't required for most use cases. +OpenRAG's CPU-only deployment doesn't prevent you from using GPU acceleration in external services, such as Ollama servers. + +GPU acceleration is required only for specific use cases, typically involving customization of the ingestion flows or ingestion logic. +For example, writing alternate ingest logic in OpenRAG that uses GPUs directly in the container, or customizing the ingestion flows to use Langflow's Docling component with GPU acceleration instead of OpenRAG's `docling serve` service. + +To deploy OpenRAG on an Amazon EC2 instance with GPU acceleration enabled, you must edit the `docker-compose.gpu.yml` file before starting the OpenRAG containers. +For more information, see [Some images failed to pull on Amazon EC2 with GPU support](/support/troubleshoot#some-images-failed-to-pull-on-amazon-ec2-with-gpu-support). \ No newline at end of file diff --git a/docs/docs/get-started/docker.mdx b/docs/docs/get-started/docker.mdx index acd4a971..fa6b966a 100644 --- a/docs/docs/get-started/docker.mdx +++ b/docs/docs/get-started/docker.mdx @@ -12,6 +12,7 @@ import PartialPrereqWindows from '@site/docs/_partial-prereq-windows.mdx'; import PartialPrereqPython from '@site/docs/_partial-prereq-python.mdx'; import PartialInstallNextSteps from '@site/docs/_partial-install-next-steps.mdx'; import PartialOllamaModels from '@site/docs/_partial-ollama-models.mdx'; +import PartialGpuModeTip from '@site/docs/_partial-gpu-mode-tip.mdx'; To manage your own OpenRAG services, deploy OpenRAG with Docker or Podman. @@ -136,15 +137,8 @@ The following variables are required or recommended: podman compose -f docker-compose.yml -f docker-compose.gpu.yml up -d ``` - tip::: - GPU acceleration isn't required for most use cases. - OpenRAG's CPU-only deployment doesn't prevent you from using GPU acceleration in external services, such as Ollama servers. - - GPU acceleration is required only for specific use cases, typically involving customization of the ingestion flows or ingestion logic. - For example, writing alternate ingest logic in OpenRAG that uses GPUs directly in the container, or customizing the ingestion flows to use Langflow's Docling component with GPU acceleration instead of the `docling serve` service. - - If you are deploying OpenRAG on an Amazon EC2 instance with GPU acceleration enabled, you must edit the `docker-compose.gpu.yml` file before deploying the OpenRAG containers. - For more information, see [Some images failed to pull on Amazon EC2 with GPU support](/support/troubleshoot#some-images-failed-to-pull-on-amazon-ec2-with-gpu-support). + :::tip + ::: 4. Wait for the OpenRAG containers to start, and then confirm that all containers are running: diff --git a/docs/docs/get-started/tui.mdx b/docs/docs/get-started/tui.mdx index 2a6c36dc..7a192c67 100644 --- a/docs/docs/get-started/tui.mdx +++ b/docs/docs/get-started/tui.mdx @@ -3,6 +3,8 @@ title: Use the TUI slug: /tui --- +import PartialGpuModeTip from '@site/docs/_partial-gpu-mode-tip.mdx'; + The OpenRAG Terminal User Interface (TUI) provides a simplified and guided experience for configuring, managing, and monitoring your OpenRAG deployment directly from the terminal. ![OpenRAG TUI Interface](@site/static/img/openrag_tui_dec_2025.png) @@ -36,6 +38,10 @@ In the TUI, click **Status**, and then click **Switch to GPU Mode** or **Switch This change requires restarting all OpenRAG services because each mode has its own `docker-compose` file. +:::tip + +::: + ## Exit the OpenRAG TUI To exit the OpenRAG TUI, press q on the TUI main page. From a3304594e55e62481ad2c8a0d900777d24bfc2fc Mon Sep 17 00:00:00 2001 From: April M <36110273+aimurphy@users.noreply.github.com> Date: Tue, 13 Jan 2026 09:59:10 -0800 Subject: [PATCH 09/21] indentation --- docs/docs/get-started/docker.mdx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/docs/get-started/docker.mdx b/docs/docs/get-started/docker.mdx index fa6b966a..1fc4e798 100644 --- a/docs/docs/get-started/docker.mdx +++ b/docs/docs/get-started/docker.mdx @@ -129,13 +129,13 @@ The following variables are required or recommended: * **GPU-accelerated deployment**: If your host machine has an NVIDIA GPU with CUDA support and compatible NVIDIA drivers, use the base `docker-compose.yml` file with the `docker-compose.gpu.yml` override: - ```bash title="Docker" - docker compose -f docker-compose.yml -f docker-compose.gpu.yml up -d - ``` + ```bash title="Docker" + docker compose -f docker-compose.yml -f docker-compose.gpu.yml up -d + ``` - ```bash title="Podman" - podman compose -f docker-compose.yml -f docker-compose.gpu.yml up -d - ``` + ```bash title="Podman" + podman compose -f docker-compose.yml -f docker-compose.gpu.yml up -d + ``` :::tip From de29a80cbadfcf2a44458414e67087e8e7811c77 Mon Sep 17 00:00:00 2001 From: ming luo Date: Tue, 13 Jan 2026 13:55:12 -0500 Subject: [PATCH 10/21] add docker compose --- .github/workflows/test-integration.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/test-integration.yml b/.github/workflows/test-integration.yml index ab40f4cd..ed6e325e 100644 --- a/.github/workflows/test-integration.yml +++ b/.github/workflows/test-integration.yml @@ -72,6 +72,12 @@ jobs: - name: Python version run: uv python install 3.13 + - name: Install docker-compose + run: | + sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose + sudo chmod +x /usr/local/bin/docker-compose + docker-compose --version + - name: Install dependencies run: uv sync From 18447c2a4e9819a13ef33c081f02faaa3f7283a7 Mon Sep 17 00:00:00 2001 From: ming luo Date: Tue, 13 Jan 2026 14:01:00 -0500 Subject: [PATCH 11/21] use sudo apt-get --- .github/workflows/test-integration.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-integration.yml b/.github/workflows/test-integration.yml index ed6e325e..c4f9555b 100644 --- a/.github/workflows/test-integration.yml +++ b/.github/workflows/test-integration.yml @@ -74,8 +74,8 @@ jobs: - name: Install docker-compose run: | - sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose - sudo chmod +x /usr/local/bin/docker-compose + sudo apt-get update + sudo apt-get install -y docker-compose docker-compose --version - name: Install dependencies From 7fa693b7b59358191ad3acff2434c0f28c40f1a2 Mon Sep 17 00:00:00 2001 From: phact Date: Tue, 13 Jan 2026 14:15:51 -0500 Subject: [PATCH 12/21] .env.example --- .env.example | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.env.example b/.env.example index 5a5f6429..849b94ad 100644 --- a/.env.example +++ b/.env.example @@ -66,6 +66,10 @@ EMBEDDING_MODEL= # OPTIONAL url for openrag link to langflow in the UI LANGFLOW_PUBLIC_URL= +# OPTIONAL: Override the full docling-serve URL (e.g., for remote instances) +# If not set, auto-detects host and uses port 5001 +# DOCLING_SERVE_URL=http://my-docling-server:5001 + # OPTIONAL: Override host for docling service (for special networking setups) # HOST_DOCKER_INTERNAL=host.containers.internal From dc5513fe508fc741675c33bf60df780d25240e83 Mon Sep 17 00:00:00 2001 From: ming Date: Tue, 13 Jan 2026 14:23:58 -0500 Subject: [PATCH 13/21] remove docker-compose test-integration.yml --- .github/workflows/test-integration.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/test-integration.yml b/.github/workflows/test-integration.yml index c4f9555b..ab40f4cd 100644 --- a/.github/workflows/test-integration.yml +++ b/.github/workflows/test-integration.yml @@ -72,12 +72,6 @@ jobs: - name: Python version run: uv python install 3.13 - - name: Install docker-compose - run: | - sudo apt-get update - sudo apt-get install -y docker-compose - docker-compose --version - - name: Install dependencies run: uv sync From 10738303a76b729695883be5b1cfc50464c23857 Mon Sep 17 00:00:00 2001 From: "April I. Murphy" <36110273+aimurphy@users.noreply.github.com> Date: Tue, 13 Jan 2026 12:19:27 -0800 Subject: [PATCH 14/21] Update docs/docusaurus.config.js --- docs/docusaurus.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index d8a9acf1..62345bb8 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -248,7 +248,7 @@ const config = { appId: "SMEA51Q5OL", // public key, safe to commit apiKey: "b2ec302e9880e8979ad6a68f0c36271e", - indexName: "openrag", + indexName: "openrag-algolia", contextualSearch: true, searchParameters: {}, searchPagePath: "search", From b4ec305652a82c1534c936cd15b3d40bdbcebd6e Mon Sep 17 00:00:00 2001 From: ming luo Date: Tue, 13 Jan 2026 16:54:24 -0500 Subject: [PATCH 15/21] fix docker build gh runner --- .github/workflows/build-multiarch.yml | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build-multiarch.yml b/.github/workflows/build-multiarch.yml index 077b66ec..d832bcd1 100644 --- a/.github/workflows/build-multiarch.yml +++ b/.github/workflows/build-multiarch.yml @@ -69,8 +69,7 @@ jobs: tag: langflowai/openrag-backend platform: linux/arm64 arch: arm64 - #runs-on: [self-hosted, linux, ARM64, langflow-ai-arm64-2] - runs-on: RagRunner + runs-on: [self-hosted, Linux, ARM64, langflow-ai-arm64-40gb] # frontend - image: frontend @@ -84,8 +83,7 @@ jobs: tag: langflowai/openrag-frontend platform: linux/arm64 arch: arm64 - #runs-on: [self-hosted, linux, ARM64, langflow-ai-arm64-2] - runs-on: RagRunner + runs-on: [self-hosted, Linux, ARM64, langflow-ai-arm64-40gb] # langflow - image: langflow @@ -99,8 +97,7 @@ jobs: tag: langflowai/openrag-langflow platform: linux/arm64 arch: arm64 - #runs-on: self-hosted - runs-on: RagRunner + runs-on: [self-hosted, Linux, ARM64, langflow-ai-arm64-40gb] # opensearch - image: opensearch @@ -114,9 +111,7 @@ jobs: tag: langflowai/openrag-opensearch platform: linux/arm64 arch: arm64 - #runs-on: [self-hosted, linux, ARM64, langflow-ai-arm64-2] - #runs-on: self-hosted - runs-on: RagRunner + runs-on: [self-hosted, Linux, ARM64, langflow-ai-arm64-40gb] runs-on: ${{ matrix.runs-on }} From 5904475a45eef44c1ffe53ab3158a7673eb2e743 Mon Sep 17 00:00:00 2001 From: ming luo Date: Tue, 13 Jan 2026 17:04:18 -0500 Subject: [PATCH 16/21] try langflow-ai-arm64-40gb-ephemeral --- .github/workflows/build-multiarch.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-multiarch.yml b/.github/workflows/build-multiarch.yml index d832bcd1..1f06553c 100644 --- a/.github/workflows/build-multiarch.yml +++ b/.github/workflows/build-multiarch.yml @@ -69,7 +69,7 @@ jobs: tag: langflowai/openrag-backend platform: linux/arm64 arch: arm64 - runs-on: [self-hosted, Linux, ARM64, langflow-ai-arm64-40gb] + runs-on: [self-hosted, Linux, ARM64, langflow-ai-arm64-40gb-ephemeral] # frontend - image: frontend @@ -83,7 +83,7 @@ jobs: tag: langflowai/openrag-frontend platform: linux/arm64 arch: arm64 - runs-on: [self-hosted, Linux, ARM64, langflow-ai-arm64-40gb] + runs-on: [self-hosted, Linux, ARM64, langflow-ai-arm64-40gb-ephemeral] # langflow - image: langflow @@ -97,7 +97,7 @@ jobs: tag: langflowai/openrag-langflow platform: linux/arm64 arch: arm64 - runs-on: [self-hosted, Linux, ARM64, langflow-ai-arm64-40gb] + runs-on: [self-hosted, Linux, ARM64, langflow-ai-arm64-40gb-ephemeral] # opensearch - image: opensearch @@ -111,7 +111,7 @@ jobs: tag: langflowai/openrag-opensearch platform: linux/arm64 arch: arm64 - runs-on: [self-hosted, Linux, ARM64, langflow-ai-arm64-40gb] + runs-on: [self-hosted, Linux, ARM64, langflow-ai-arm64-40gb-ephemeral] runs-on: ${{ matrix.runs-on }} From 2dbb27634ac694743d711d2263fa9b4886c38a54 Mon Sep 17 00:00:00 2001 From: Mike Fortman Date: Wed, 14 Jan 2026 13:21:03 -0600 Subject: [PATCH 17/21] Upgrade to node LTS version including security fix --- Dockerfile.frontend | 2 +- frontend/package.json | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Dockerfile.frontend b/Dockerfile.frontend index f46b431d..3ab6d8ac 100644 --- a/Dockerfile.frontend +++ b/Dockerfile.frontend @@ -1,4 +1,4 @@ -FROM node:18-slim +FROM node:20.20.0-slim # Set working directory WORKDIR /app diff --git a/frontend/package.json b/frontend/package.json index 897f0c4c..ca131f61 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -2,6 +2,9 @@ "name": "frontend", "version": "0.1.0", "private": true, + "engines": { + "node": ">=20.20.0" + }, "scripts": { "dev": "next dev", "build": "next build", From 70bf08e7ec4e38d261ac248d85f2c1217dc76c62 Mon Sep 17 00:00:00 2001 From: April M <36110273+aimurphy@users.noreply.github.com> Date: Thu, 15 Jan 2026 07:12:06 -0800 Subject: [PATCH 18/21] remove ec2 troubleshooting --- docs/docs/_partial-gpu-mode-tip.mdx | 5 +---- docs/docs/support/troubleshoot.mdx | 27 --------------------------- 2 files changed, 1 insertion(+), 31 deletions(-) diff --git a/docs/docs/_partial-gpu-mode-tip.mdx b/docs/docs/_partial-gpu-mode-tip.mdx index 6a828ef8..d9d229fb 100644 --- a/docs/docs/_partial-gpu-mode-tip.mdx +++ b/docs/docs/_partial-gpu-mode-tip.mdx @@ -2,7 +2,4 @@ GPU acceleration isn't required for most use cases. OpenRAG's CPU-only deployment doesn't prevent you from using GPU acceleration in external services, such as Ollama servers. GPU acceleration is required only for specific use cases, typically involving customization of the ingestion flows or ingestion logic. -For example, writing alternate ingest logic in OpenRAG that uses GPUs directly in the container, or customizing the ingestion flows to use Langflow's Docling component with GPU acceleration instead of OpenRAG's `docling serve` service. - -To deploy OpenRAG on an Amazon EC2 instance with GPU acceleration enabled, you must edit the `docker-compose.gpu.yml` file before starting the OpenRAG containers. -For more information, see [Some images failed to pull on Amazon EC2 with GPU support](/support/troubleshoot#some-images-failed-to-pull-on-amazon-ec2-with-gpu-support). \ No newline at end of file +For example, writing alternate ingest logic in OpenRAG that uses GPUs directly in the container, or customizing the ingestion flows to use Langflow's Docling component with GPU acceleration instead of OpenRAG's `docling serve` service. \ No newline at end of file diff --git a/docs/docs/support/troubleshoot.mdx b/docs/docs/support/troubleshoot.mdx index fa1cdaa4..f4d69e6e 100644 --- a/docs/docs/support/troubleshoot.mdx +++ b/docs/docs/support/troubleshoot.mdx @@ -35,33 +35,6 @@ open "/Applications/Python VERSION/Install Certificates.command" Replace `VERSION` with your installed Python version, such as `3.13`. -### Some images failed to pull on Amazon EC2 with GPU support {#some-images-failed-to-pull-on-amazon-ec2-with-gpu-support} - -When installing OpenRAG on an Amazon EC2 instance with GPU acceleration enabled, some Docker images might fail to pull. - -To resolve this issue, do the following: - -1. [Stop the OpenRAG containers](/manage-services#stop-and-start-containers). - -2. In your `~/.openrag` directory, edit the `docker-compose.gpu.yml` file as follows: - - ```yaml - services: - openrag-backend: - environment: - - NVIDIA_DRIVER_CAPABILITIES=compute,utility - - NVIDIA_VISIBLE_DEVICES=all - deploy: - resources: - reservations: - devices: - - driver: nvidia - count: all - capabilities: [gpu] - ``` - -3. [Restart the OpenRAG containers](/manage-services#stop-and-start-containers). - ### Application onboarding gets stuck on Google Chrome If the OpenRAG onboarding process gets stuck when using Google Chrome, try clearing your browser's cache. From 2bf88d8f5c4604d4c85da826476f7a8d4fde3818 Mon Sep 17 00:00:00 2001 From: phact Date: Thu, 15 Jan 2026 11:50:34 -0500 Subject: [PATCH 19/21] add flow configmaps to helm chart --- .../flows/agent-flow-configmap.yaml | 12 +++++++ .../flows/ingestion-flow-configmap.yaml | 12 +++++++ .../flows/nudges-flow-configmap.yaml | 12 +++++++ .../configmaps/flows/url-flow-configmap.yaml | 12 +++++++ .../templates/langflow/deployment.yaml | 36 +++++++++++++++++++ helm/openrag/values.yaml | 1 + 6 files changed, 85 insertions(+) create mode 100644 helm/openrag/templates/configmaps/flows/agent-flow-configmap.yaml create mode 100644 helm/openrag/templates/configmaps/flows/ingestion-flow-configmap.yaml create mode 100644 helm/openrag/templates/configmaps/flows/nudges-flow-configmap.yaml create mode 100644 helm/openrag/templates/configmaps/flows/url-flow-configmap.yaml diff --git a/helm/openrag/templates/configmaps/flows/agent-flow-configmap.yaml b/helm/openrag/templates/configmaps/flows/agent-flow-configmap.yaml new file mode 100644 index 00000000..cff35fe9 --- /dev/null +++ b/helm/openrag/templates/configmaps/flows/agent-flow-configmap.yaml @@ -0,0 +1,12 @@ +{{- if .Values.langflow.flows.loadDefaults }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "openrag.fullname" . }}-flow-agent + namespace: {{ include "openrag.namespace" . }} + labels: + {{- include "openrag.labels" . | nindent 4 }} +data: + openrag_agent.json: |- +{{ .Files.Get "flows/openrag_agent.json" | indent 4 }} +{{- end }} diff --git a/helm/openrag/templates/configmaps/flows/ingestion-flow-configmap.yaml b/helm/openrag/templates/configmaps/flows/ingestion-flow-configmap.yaml new file mode 100644 index 00000000..ad236517 --- /dev/null +++ b/helm/openrag/templates/configmaps/flows/ingestion-flow-configmap.yaml @@ -0,0 +1,12 @@ +{{- if .Values.langflow.flows.loadDefaults }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "openrag.fullname" . }}-flow-ingestion + namespace: {{ include "openrag.namespace" . }} + labels: + {{- include "openrag.labels" . | nindent 4 }} +data: + ingestion_flow.json: |- +{{ .Files.Get "flows/ingestion_flow.json" | indent 4 }} +{{- end }} diff --git a/helm/openrag/templates/configmaps/flows/nudges-flow-configmap.yaml b/helm/openrag/templates/configmaps/flows/nudges-flow-configmap.yaml new file mode 100644 index 00000000..5ebe05fb --- /dev/null +++ b/helm/openrag/templates/configmaps/flows/nudges-flow-configmap.yaml @@ -0,0 +1,12 @@ +{{- if .Values.langflow.flows.loadDefaults }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "openrag.fullname" . }}-flow-nudges + namespace: {{ include "openrag.namespace" . }} + labels: + {{- include "openrag.labels" . | nindent 4 }} +data: + openrag_nudges.json: |- +{{ .Files.Get "flows/openrag_nudges.json" | indent 4 }} +{{- end }} diff --git a/helm/openrag/templates/configmaps/flows/url-flow-configmap.yaml b/helm/openrag/templates/configmaps/flows/url-flow-configmap.yaml new file mode 100644 index 00000000..911ee5e4 --- /dev/null +++ b/helm/openrag/templates/configmaps/flows/url-flow-configmap.yaml @@ -0,0 +1,12 @@ +{{- if .Values.langflow.flows.loadDefaults }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "openrag.fullname" . }}-flow-url + namespace: {{ include "openrag.namespace" . }} + labels: + {{- include "openrag.labels" . | nindent 4 }} +data: + openrag_url_mcp.json: |- +{{ .Files.Get "flows/openrag_url_mcp.json" | indent 4 }} +{{- end }} diff --git a/helm/openrag/templates/langflow/deployment.yaml b/helm/openrag/templates/langflow/deployment.yaml index f583f9a1..54ba3db8 100644 --- a/helm/openrag/templates/langflow/deployment.yaml +++ b/helm/openrag/templates/langflow/deployment.yaml @@ -30,6 +30,29 @@ spec: imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} + {{- if .Values.langflow.flows.loadDefaults }} + initContainers: + - name: load-default-flows + image: busybox:1.36 + command: + - /bin/sh + - -c + - | + FLOWS_DIR="{{ .Values.langflow.persistence.mountPath }}/{{ .Values.langflow.persistence.flowsSubPath }}" + mkdir -p "$FLOWS_DIR" + if [ -z "$(ls -A $FLOWS_DIR 2>/dev/null)" ]; then + echo "Loading default flows..." + cp /default-flows/*.json "$FLOWS_DIR/" + echo "Flows loaded: $(ls $FLOWS_DIR)" + else + echo "Flows already exist, skipping." + fi + volumeMounts: + - name: langflow-data + mountPath: {{ .Values.langflow.persistence.mountPath }} + - name: default-flows + mountPath: /default-flows + {{- end }} containers: - name: langflow image: "{{ .Values.langflow.image.repository }}:{{ .Values.langflow.image.tag | default .Values.global.imageTag }}" @@ -196,6 +219,19 @@ spec: {{- else }} emptyDir: {} {{- end }} + {{- if .Values.langflow.flows.loadDefaults }} + - name: default-flows + projected: + sources: + - configMap: + name: {{ include "openrag.fullname" . }}-flow-ingestion + - configMap: + name: {{ include "openrag.fullname" . }}-flow-agent + - configMap: + name: {{ include "openrag.fullname" . }}-flow-nudges + - configMap: + name: {{ include "openrag.fullname" . }}-flow-url + {{- end }} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} diff --git a/helm/openrag/values.yaml b/helm/openrag/values.yaml index c589ea74..ade7e1fa 100644 --- a/helm/openrag/values.yaml +++ b/helm/openrag/values.yaml @@ -71,6 +71,7 @@ langflow: # Flow configuration (UUIDs for Langflow workflows) flows: + loadDefaults: true # Load default OpenRAG flows on first deployment chatFlowId: "1098eea1-6649-4e1d-aed1-b77249fb8dd0" ingestFlowId: "5488df7c-b93f-4f87-a446-b67028bc0813" urlIngestFlowId: "72c3d17c-2dac-4a73-b48a-6518473d7830" From 88c09846c0a399759c0c6d73c69ce34c474edba7 Mon Sep 17 00:00:00 2001 From: Mendon Kissling <59585235+mendonk@users.noreply.github.com> Date: Thu, 15 Jan 2026 13:23:55 -0500 Subject: [PATCH 20/21] Docs: Upgrade to node LTS version including security fix (#787) * upgrade-node-for-security-fix * package-lock --- .github/workflows/deploy-docs-draft.yml | 2 +- .github/workflows/deploy-gh-pages.yml | 2 +- docs/package-lock.json | 2 +- docs/package.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/deploy-docs-draft.yml b/.github/workflows/deploy-docs-draft.yml index 23040384..7bad9982 100644 --- a/.github/workflows/deploy-docs-draft.yml +++ b/.github/workflows/deploy-docs-draft.yml @@ -23,7 +23,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 20.20.0 cache: npm cache-dependency-path: ./docs/package-lock.json diff --git a/.github/workflows/deploy-gh-pages.yml b/.github/workflows/deploy-gh-pages.yml index a751638f..171a752f 100644 --- a/.github/workflows/deploy-gh-pages.yml +++ b/.github/workflows/deploy-gh-pages.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 20.20.0 cache: npm cache-dependency-path: ./docs/package-lock.json diff --git a/docs/package-lock.json b/docs/package-lock.json index 41a104d0..a41d11e3 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -26,7 +26,7 @@ "typescript": "~5.9.3" }, "engines": { - "node": ">=18.0" + "node": ">=20.20.0" } }, "node_modules/@ai-sdk/gateway": { diff --git a/docs/package.json b/docs/package.json index 2bd2f7f4..041bb207 100644 --- a/docs/package.json +++ b/docs/package.json @@ -46,6 +46,6 @@ ] }, "engines": { - "node": ">=18.0" + "node": ">=20.20.0" } } From bc639d190b75da756ffc13eb28e8b3b14d40ed5e Mon Sep 17 00:00:00 2001 From: ming luo Date: Thu, 15 Jan 2026 15:30:04 -0500 Subject: [PATCH 21/21] opensearch health check --- src/main.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/main.py b/src/main.py index 710b3dab..fd2bf2a7 100644 --- a/src/main.py +++ b/src/main.py @@ -21,6 +21,7 @@ from functools import partial from starlette.applications import Starlette from starlette.routing import Route +from starlette.responses import JSONResponse # Set multiprocessing start method to 'spawn' for CUDA compatibility multiprocessing.set_start_method("spawn", force=True) @@ -456,6 +457,24 @@ async def _ingest_default_documents_langflow(services, file_paths): file_count=len(file_paths), ) +async def opensearch_health_ready(request): + """Readiness probe: verifies OpenSearch dependency is reachable.""" + try: + # Fast check that the cluster is reachable/auth works + await asyncio.wait_for(clients.opensearch.info(), timeout=5.0) + return JSONResponse( + {"status": "ready", "dependencies": {"opensearch": "up"}}, + status_code=200, + ) + except Exception as e: + return JSONResponse( + { + "status": "not_ready", + "dependencies": {"opensearch": "down"}, + "error": str(e), + }, + status_code=503, + ) async def _ingest_default_documents_openrag(services, file_paths): """Ingest default documents using traditional OpenRAG processor.""" @@ -1148,6 +1167,11 @@ async def create_app(): ), methods=["GET"], ), + Route( + "/search/health", + opensearch_health_ready, + methods=["GET"], + ), # Models endpoints Route( "/models/openai",