feat: add optional vector database and semantic search to helm chart

Add support for deploying Qdrant vector database and Ollama embedding
service as optional helm chart dependencies. Enables semantic search
capabilities for Nextcloud content with flexible deployment options.

Chart Dependencies:
- Add Qdrant v0.9.0 from qdrant/qdrant-helm (conditional)
- Add Ollama v1.33.0 from otwld/ollama-helm (conditional)
- Both dependencies only deploy when enabled

Configuration (values.yaml):
- vectorSync: Background sync settings (interval, workers, queue size)
- qdrant: Subchart config with persistence, resources, clustering
- ollama: Subchart config with model pull, persistence, resources
  - Support for external Ollama via ollama.url (no subchart deployment)
- openai: Alternative embedding provider (OpenAI or compatible API)

Environment Variables (deployment.yaml):
- VECTOR_SYNC_* variables when vectorSync.enabled
- QDRANT_URL, QDRANT_COLLECTION when qdrant.enabled
- OLLAMA_BASE_URL, OLLAMA_EMBEDDING_MODEL when ollama enabled or URL set
- OPENAI_API_KEY when openai.enabled

Documentation:
- README: New "Vector Search & Semantic Capabilities" section
- README: Example 5 showing three deployment patterns
- NOTES.txt: Conditional guidance when vector features enabled
- Secret template for OpenAI API key management

All features disabled by default for backward compatibility.
Tested with helm template and helm lint.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Chris Coutinho
2025-11-09 00:02:48 +01:00
parent ee183e1c1c
commit e32c8f4aec
8 changed files with 343 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
charts/
+9
View File
@@ -0,0 +1,9 @@
dependencies:
- name: qdrant
repository: https://qdrant.github.io/qdrant-helm
version: 0.9.0
- name: ollama
repository: https://otwld.github.io/ollama-helm
version: 1.33.0
digest: sha256:c53b7a604d202460f60408a62025ae837cad8d4da970b1e5bb404e2b41289f94
generated: "2025-11-08T23:44:59.709689907+01:00"
+9
View File
@@ -21,3 +21,12 @@ home: https://github.com/cbcoutinho/nextcloud-mcp-server
sources:
- https://github.com/cbcoutinho/nextcloud-mcp-server
icon: https://raw.githubusercontent.com/nextcloud/server/master/core/img/logo/logo.svg
dependencies:
- name: qdrant
version: "0.9.0"
repository: https://qdrant.github.io/qdrant-helm
condition: qdrant.enabled
- name: ollama
version: "1.33.0"
repository: https://otwld.github.io/ollama-helm
condition: ollama.enabled
+145
View File
@@ -202,6 +202,67 @@ The application exposes HTTP health check endpoints:
| `documentProcessing.unstructured.apiUrl` | Unstructured API URL | `http://unstructured:8000` |
| `documentProcessing.tesseract.enabled` | Enable Tesseract OCR | `false` |
#### Vector Search & Semantic Capabilities (Optional)
Enable semantic search capabilities by deploying a vector database (Qdrant) and embedding service (Ollama or OpenAI).
**Vector Sync Configuration:**
| Parameter | Description | Default |
|-----------|-------------|---------|
| `vectorSync.enabled` | Enable background vector synchronization | `false` |
| `vectorSync.scanInterval` | Scan interval in seconds | `3600` |
| `vectorSync.processorWorkers` | Number of concurrent processor workers | `3` |
| `vectorSync.queueMaxSize` | Maximum queue size for pending documents | `10000` |
**Qdrant Vector Database:**
Qdrant is deployed as a subchart when `qdrant.enabled` is `true`. All configuration values are passed through to the [qdrant/qdrant](https://github.com/qdrant/qdrant-helm) chart.
| Parameter | Description | Default |
|-----------|-------------|---------|
| `qdrant.enabled` | Deploy Qdrant as a subchart | `false` |
| `qdrant.replicaCount` | Number of Qdrant replicas | `1` |
| `qdrant.image.tag` | Qdrant version | `v1.12.5` |
| `qdrant.apiKey` | Optional API key for authentication | `""` |
| `qdrant.persistence.size` | Storage size for vector data | `10Gi` |
| `qdrant.persistence.storageClass` | Storage class | `""` |
| `qdrant.resources.requests.cpu` | CPU request | `200m` |
| `qdrant.resources.requests.memory` | Memory request | `512Mi` |
| `qdrant.resources.limits.cpu` | CPU limit | `1000m` |
| `qdrant.resources.limits.memory` | Memory limit | `2Gi` |
**Ollama Embedding Service:**
Ollama is deployed as a subchart when `ollama.enabled` is `true`. All configuration values are passed through to the [ollama/ollama](https://github.com/otwld/ollama-helm) chart. Alternatively, set `ollama.url` to use an external Ollama instance.
| Parameter | Description | Default |
|-----------|-------------|---------|
| `ollama.enabled` | Deploy Ollama as a subchart | `false` |
| `ollama.url` | External Ollama URL (use with `enabled: false`) | `""` |
| `ollama.embeddingModel` | Embedding model to use | `nomic-embed-text` |
| `ollama.verifySsl` | Verify SSL certificates | `true` |
| `ollama.replicaCount` | Number of Ollama replicas | `1` |
| `ollama.ollama.models.pull` | Models to pull on startup | `["nomic-embed-text"]` |
| `ollama.persistentVolume.enabled` | Enable persistent storage | `true` |
| `ollama.persistentVolume.size` | Storage size for models | `20Gi` |
| `ollama.resources.requests.cpu` | CPU request | `500m` |
| `ollama.resources.requests.memory` | Memory request | `1Gi` |
| `ollama.resources.limits.cpu` | CPU limit | `2000m` |
| `ollama.resources.limits.memory` | Memory limit | `4Gi` |
**OpenAI Embedding Provider (Alternative):**
Use OpenAI or any OpenAI-compatible API instead of Ollama.
| Parameter | Description | Default |
|-----------|-------------|---------|
| `openai.enabled` | Enable OpenAI embedding provider | `false` |
| `openai.apiKey` | OpenAI API key | `""` |
| `openai.existingSecret` | Use existing secret for API key | `""` |
| `openai.secretKey` | Key in secret containing API key | `api-key` |
| `openai.baseUrl` | Custom API endpoint (optional) | `""` |
## Examples
### Example 1: Basic Auth with Ingress
@@ -379,6 +440,90 @@ affinity:
topologyKey: kubernetes.io/hostname
```
### Example 5: Semantic Search with Qdrant and Ollama
Deploy with vector search capabilities using embedded Qdrant and Ollama:
```yaml
nextcloud:
host: https://cloud.example.com
auth:
mode: basic
basic:
username: admin
password: secure-password
# Enable vector sync
vectorSync:
enabled: true
scanInterval: 1800 # Scan every 30 minutes
processorWorkers: 5
# Deploy Qdrant as a subchart
qdrant:
enabled: true
persistence:
size: 20Gi
storageClass: fast-ssd
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 2000m
memory: 4Gi
# Deploy Ollama as a subchart
ollama:
enabled: true
embeddingModel: nomic-embed-text
persistentVolume:
size: 30Gi
storageClass: standard
resources:
requests:
cpu: 1000m
memory: 2Gi
limits:
cpu: 4000m
memory: 8Gi
```
Or use an external Ollama instance:
```yaml
vectorSync:
enabled: true
qdrant:
enabled: true
# Use external Ollama instead of deploying subchart
ollama:
enabled: false
url: "http://ollama.ai-services.svc.cluster.local:11434"
embeddingModel: nomic-embed-text
```
Or use OpenAI for embeddings:
```yaml
vectorSync:
enabled: true
qdrant:
enabled: true
# Use OpenAI instead of Ollama
openai:
enabled: true
apiKey: "sk-..."
# Or use existing secret:
# existingSecret: openai-api-key
# secretKey: api-key
```
## Upgrading
### To upgrade an existing deployment:
@@ -69,6 +69,33 @@ Your Nextcloud MCP Server has been deployed in {{ .Values.auth.mode }} authentic
{{- end }}
{{- end }}
{{- if .Values.vectorSync.enabled }}
5. Vector Search & Semantic Capabilities:
- Vector Sync: Enabled
- Scan Interval: {{ .Values.vectorSync.scanInterval }}s
- Processor Workers: {{ .Values.vectorSync.processorWorkers }}
{{- if .Values.qdrant.enabled }}
- Qdrant: Deployed as subchart ({{ .Release.Name }}-qdrant:6333)
{{- else }}
- Qdrant: Not deployed (configure external instance)
{{- end }}
{{- if .Values.ollama.enabled }}
- Ollama: Deployed as subchart ({{ .Release.Name }}-ollama:11434)
- Embedding Model: {{ .Values.ollama.embeddingModel }}
{{- else if .Values.ollama.url }}
- Ollama: Using external instance at {{ .Values.ollama.url }}
- Embedding Model: {{ .Values.ollama.embeddingModel }}
{{- else if .Values.openai.enabled }}
- OpenAI: Enabled for embeddings
{{- else }}
- WARNING: No embedding provider configured (Ollama or OpenAI required)
{{- end }}
Check vector sync status:
kubectl --namespace {{ .Release.Namespace }} exec -it deploy/{{ include "nextcloud-mcp-server.fullname" . }} -- curl -s http://localhost:{{ include "nextcloud-mcp-server.port" . }}/user/page | grep "Vector Sync"
{{- end }}
For more information and documentation:
- GitHub: https://github.com/cbcoutinho/nextcloud-mcp-server
- Documentation: https://github.com/cbcoutinho/nextcloud-mcp-server#readme
@@ -140,6 +140,52 @@ spec:
value: {{ .Values.documentProcessing.custom.types | quote }}
{{- end }}
{{- end }}
# Vector Sync
- name: VECTOR_SYNC_ENABLED
value: {{ .Values.vectorSync.enabled | quote }}
{{- if .Values.vectorSync.enabled }}
- name: VECTOR_SYNC_SCAN_INTERVAL
value: {{ .Values.vectorSync.scanInterval | quote }}
- name: VECTOR_SYNC_PROCESSOR_WORKERS
value: {{ .Values.vectorSync.processorWorkers | quote }}
- name: VECTOR_SYNC_QUEUE_MAX_SIZE
value: {{ .Values.vectorSync.queueMaxSize | quote }}
{{- end }}
# Qdrant Vector Database
{{- if .Values.qdrant.enabled }}
- name: QDRANT_URL
value: "http://{{ .Release.Name }}-qdrant:6333"
- name: QDRANT_COLLECTION
value: "nextcloud_content"
{{- if .Values.qdrant.apiKey }}
- name: QDRANT_API_KEY
valueFrom:
secretKeyRef:
name: {{ .Release.Name }}-qdrant
key: api-key
{{- end }}
{{- end }}
# Ollama Embedding Service
{{- if or .Values.ollama.enabled .Values.ollama.url }}
- name: OLLAMA_BASE_URL
value: {{ .Values.ollama.url | default (printf "http://%s-ollama:11434" .Release.Name) | quote }}
- name: OLLAMA_EMBEDDING_MODEL
value: {{ .Values.ollama.embeddingModel | quote }}
- name: OLLAMA_VERIFY_SSL
value: {{ .Values.ollama.verifySsl | quote }}
{{- end }}
# OpenAI Embedding Provider (alternative to Ollama)
{{- if .Values.openai.enabled }}
- name: OPENAI_API_KEY
valueFrom:
secretKeyRef:
name: {{ .Values.openai.existingSecret | default (printf "%s-openai" (include "nextcloud-mcp-server.fullname" .)) }}
key: {{ .Values.openai.secretKey }}
{{- if .Values.openai.baseUrl }}
- name: OPENAI_BASE_URL
value: {{ .Values.openai.baseUrl | quote }}
{{- end }}
{{- end }}
{{- with .Values.extraEnv }}
{{- toYaml . | nindent 12 }}
{{- end }}
@@ -0,0 +1,11 @@
{{- if and .Values.openai.enabled (not .Values.openai.existingSecret) }}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "nextcloud-mcp-server.fullname" . }}-openai
labels:
{{- include "nextcloud-mcp-server.labels" . | nindent 4 }}
type: Opaque
data:
{{ .Values.openai.secretKey }}: {{ .Values.openai.apiKey | b64enc | quote }}
{{- end }}
+95
View File
@@ -264,3 +264,98 @@ extraEnvFrom: []
# name: my-configmap
# - secretRef:
# name: my-secret
# Vector Sync Configuration
# Background synchronization of Nextcloud content into vector database for semantic search
vectorSync:
# Enable background vector synchronization
enabled: false
# Scan interval in seconds (how often to check for changes)
scanInterval: 3600
# Number of concurrent processor workers
processorWorkers: 3
# Maximum queue size for documents pending indexing
queueMaxSize: 10000
# Qdrant Vector Database
# Deployed as a subchart when enabled. All values are passed through to the qdrant/qdrant chart.
# See https://github.com/qdrant/qdrant-helm for full configuration options.
qdrant:
# Enable Qdrant subchart deployment
enabled: false
# Number of Qdrant replicas
replicaCount: 1
image:
# Qdrant version
tag: v1.12.5
# Optional API key for Qdrant authentication
apiKey: ""
config:
cluster:
# Enable distributed cluster mode
enabled: false
# Persistent storage for vector data
persistence:
size: 10Gi
storageClass: ""
accessModes:
- ReadWriteOnce
# Resource limits and requests
resources:
requests:
cpu: 200m
memory: 512Mi
limits:
cpu: 1000m
memory: 2Gi
# Ollama Embedding Service
# Deployed as a subchart when enabled. All values are passed through to the ollama/ollama chart.
# See https://github.com/otwld/ollama-helm for full configuration options.
ollama:
# Enable Ollama subchart deployment
# Set to true to deploy Ollama as a subchart, or false to use an external Ollama instance
enabled: false
# External Ollama URL (use this if you have Ollama deployed elsewhere)
# When set, use enabled: false to prevent deploying the subchart
# Example: "http://ollama.default.svc.cluster.local:11434"
url: ""
# Embedding model to use
embeddingModel: "nomic-embed-text"
# Verify SSL certificates when connecting to Ollama
verifySsl: true
# Number of Ollama replicas (only used when subchart is deployed)
replicaCount: 1
# Ollama configuration (only used when subchart is deployed)
ollama:
# Models to automatically pull on startup
models:
pull:
- nomic-embed-text
# Persistent storage for models (only used when subchart is deployed)
persistentVolume:
enabled: true
size: 20Gi
storageClass: ""
# Resource limits and requests (only used when subchart is deployed)
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 2000m
memory: 4Gi
# OpenAI-compatible Embedding Provider
# Alternative to Ollama for embedding generation. Can be used with OpenAI or any compatible API.
openai:
# Enable OpenAI embedding provider
enabled: false
# OpenAI API key (only used if existingSecret is not set)
apiKey: ""
# Name of existing secret containing the API key
existingSecret: ""
# Key in the secret that contains the API key
secretKey: "api-key"
# Optional custom API endpoint (e.g., for Azure OpenAI or local compatible services)
baseUrl: ""