Skip to content
26 changes: 26 additions & 0 deletions deployment/helm-chart/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
apiVersion: v2
name: wren
description: A Helm chart for Wren AI Service
type: application
version: 1.0.0
appVersion: "0.22.2"
keywords:
- ai
- analytics
- data
home: https://github.com/Canner/WrenAI
sources:
- https://github.com/Canner/WrenAI
maintainers:
- name: Wren AI Team
email: [email protected]

dependencies:
- name: qdrant
version: "1.14.0"
repository: "https://qdrant.github.io/qdrant-helm"
condition: qdrant.enabled
- name: postgresql
version: "15.5.30"
repository: "https://charts.bitnami.com/bitnami"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/bitnami/charts
this was deprecated

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, let me update it with most used opensource postgressql chart available. Thanks @dnascimento

condition: postgresql.enabled
34 changes: 34 additions & 0 deletions deployment/helm-chart/NOTES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
1. Get the application URL by running these commands:
{{- if contains "NodePort" .Values.ui.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "wren-ai.fullname" . }}-ui-svc)
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.ui.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "wren-ai.fullname" . }}-ui-svc'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "wren-ai.fullname" . }}-ui-svc --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.ui.service.port }}
{{- else if contains "ClusterIP" .Values.ui.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "wren-ai.name" . }},app.kubernetes.io/instance1. Get the application URL by running these commands:
{{- if contains "NodePort" .Values.aiService.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "wren-ai.fullname" . }}-ai-service-svc)
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.aiService.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "wren-ai.fullname" . }}-ai-service-svc'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "wren-ai.fullname" . }}-ai-service-svc --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.aiService.service.port }}
{{- else if contains "ClusterIP" .Values.aiService.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "wren-ai.name" . }},app.kubernetes.io/instance={{ .Release.Name }},app.kubernetes.io/component=ai-service" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
{{- end }}

Service Details:
- AI Service Port: {{ .Values.config.ports.aiService }}
- Replicas: {{ .Values.aiService.replicaCount }}
- Version: {{ .Values.global.versions.aiService }}

For more information about Wren AI, visit: https://docs.getwren.ai
122 changes: 122 additions & 0 deletions deployment/helm-chart/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# Deployment of Wren AI to Kubernetes with Helm Chart
1. Ensure you satisfy the dependencies required to deploy Wren AI.
2. Adjust the values accordingly to fit your Kubernetes environment.
3. Secrets vales can be deployed together or separately.
Note: Without authentication, once you publish this on the internet, anyone can access your app, see your data, and modify your settings!

## Dependencies used in this kustomization:
- nginx.ingress
- external-dns
- cert-manager
- kubectl
- helm

## Steps to deploy:

`Suggestion`: Before deploying, check out the Helm values in the `deployment/helm ` file and modify them to suit your Kubernetes environment.

The `deployment/helm` folder contains a `values.yaml` file that will inflate the manifests into a `deployment/helm/template` files used to deploy the app to your Kubernetes cluster.

Comment on lines +16 to +19
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix path inconsistencies: use deployment/helm-chart everywhere.

Current text mixes deployment/helm and deployment/helm-chart, and the -f path points to a non-existent file. This will cause failed installs.

Apply:

-`Suggestion`: Before deploying, check out the Helm values in the `deployment/helm ` file and modify them to suit your Kubernetes environment.
+`Suggestion`: Before deploying, check out the Helm values in the `deployment/helm-chart` folder and modify them to suit your Kubernetes environment.

-The `deployment/helm` folder contains a `values.yaml` file that will inflate the manifests into a `deployment/helm/template` files used to deploy the app to your Kubernetes cluster.
+The `deployment/helm-chart` folder contains a `values.yaml` file that renders templates under `deployment/helm-chart/templates` used to deploy the app to your Kubernetes cluster.

-# Download Wren AI dependency charts like Qdrant or postgresql
-helm dependency build ./deployment/helm-chart
+# Download Wren AI dependency charts like Qdrant or PostgreSQL
+helm dependency build deployment/helm-chart

 # Deploy Wren AI with Helm
-helm upgrade --install wrenai ./deployment/helm-chart \
+helm upgrade --install wrenai deployment/helm-chart \
   --namespace wren \
-  -f deployment/helm/values.yaml \
+  -f deployment/helm-chart/values.yaml \

-### Notes on Helm:
-- `deployment/helm/values.yaml` is the main file responsible for versions of other apps such as Qdrant and PostgreSQL, version of your Wren AI app. It also combines resourses from the manifest such as ConfigMaps, Deployments, and Services. And example Ingress and Secrets.
-- `deployment/helm/template` is the manifests folder that contains the core Wren AI manifest templates, its less likely you need to modify them, but check just in case
-- `deployment/helm/charts` is directory contains any dependent Helm charts (subcharts) required by Wren AI, such as PostgreSQL or Qdrant. These dependencies are either added manually or using `helm dependency add`, and they are used to deploy third-party services alongside Wren AI.
-- `deployment/helm/Chart.yaml` This file defines the metadata for the Helm chart used to deploy Wren AI. It includes the chart name, version, application version, dependencies and a description. Helm uses this file to identify and manage the chart during installation and upgrades.
+### Notes on Helm
+- `deployment/helm-chart/values.yaml` is the main file responsible for versions of other apps such as Qdrant and PostgreSQL, and the Wren AI app. It also combines resources from the manifests such as ConfigMaps, Deployments, Services, example Ingress, and Secrets.
+- `deployment/helm-chart/templates` contains the core Wren AI manifest templates; it’s less likely you need to modify them—verify first.
+- `deployment/helm-chart/charts` contains dependent Helm charts (subcharts) required by Wren AI, such as PostgreSQL or Qdrant. These are added via `helm dependency add` and deployed alongside Wren AI.
+- `deployment/helm-chart/Chart.yaml` defines chart metadata (name, version, appVersion, dependencies, description) used during install/upgrade.

Also applies to: 58-65, 69-74

🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

16-16: Spaces inside code span elements

(MD038, no-space-in-code)

🤖 Prompt for AI Agents
In deployment/helm-chart/README.md around lines 16 to 19 (also apply same fixes
to lines 58-65 and 69-74), update all occurrences of the incorrect path
"deployment/helm" to the canonical "deployment/helm-chart", and fix any example
-f flags or file references so they point to the existing
deployment/helm-chart/values.yaml (and template references to
deployment/helm-chart/templates or deployment/helm-chart/templates/* as
appropriate); ensure every mention and command uses the exact same
deployment/helm-chart path so installs reference real files.

```shell
# Clone the repository with Helm chart
git clone https://github.com/Canner/WrenAI.git
cd WrenAI

# Create namespace
kubectl create namespace wren

Comment on lines +20 to +27
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

🧩 Analysis chain

Verify chart/secret wiring matches docs.

Ensure templates reference wren-secret and the exact key names (OPENAI_API_KEY, PG_URL, etc.), and that NOTES/values align with README.

Also applies to: 58-67, 69-74, 75-85


🏁 Script executed:

#!/bin/bash
# Confirm secret refs and values paths
rg -n -C2 -g 'deployment/helm-chart/**' \
  -e 'secretKeyRef:\s*name:\s*wren-secret' \
  -e 'key:\s*(OPENAI_API_KEY|PG_URL|PG_USERNAME|PG_PASSWORD|PG_ADMIN_PASSWORD|LANGFUSE_PUBLIC_KEY|LANGFUSE_SECRET_KEY|POSTHOG_API_KEY|USER_UUID)'
echo "---- Check values file and NOTES paths ----"
rg -n -C1 -g 'deployment/helm-chart/**' 'values.yaml|wren-secret|ingress|tls|postgresql'

Length of output: 15247


Update README secret creation to match chart templates' secret keys

  • Templates reference the secret via {{ $secretName }} (values.yaml sets existingSecretName/existingSecret = "wren-secret": deployment/helm-chart/values.yaml:19,283) and expect these keys: OPENAI_API_KEY (or GEMINI_API_KEY alternative), PG_URL, PG_USERNAME, PG_PASSWORD, USER_UUID, POSTHOG_API_KEY, LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY — see deployment/helm-chart/templates/{ai-service-deployment.yaml,ui-deployment.yaml,engine-deployment.yaml}.
  • README's example only creates wren-secret with OPENAI_API_KEY (deployment/helm-chart/README.md:45-46). Update README/NOTES to create all required secret keys or clearly document which keys are optional/conditional (e.g., GEMINI vs OPENAI, Langfuse/PostHog).
🤖 Prompt for AI Agents
In deployment/helm-chart/README.md around lines 20 to 27, the README currently
only shows creating the namespace and later creates a secret with just
OPENAI_API_KEY; update the README/NOTES to either (A) show creating the expected
Kubernetes secret (wren-secret) populated with all keys referenced by the chart
templates—OPENAI_API_KEY (or GEMINI_API_KEY alternative), PG_URL, PG_USERNAME,
PG_PASSWORD, USER_UUID, POSTHOG_API_KEY, LANGFUSE_PUBLIC_KEY,
LANGFUSE_SECRET_KEY—or (B) clearly document which keys are optional and which
are mutually exclusive (e.g., GEMINI vs OPENAI, Langfuse vs PostHog) and where
to set existingSecretName/values; adjust examples and NOTES accordingly so the
secret names/keys match deployment/helm-chart/templates and values.yaml.

# !!!!!!!!!!!!
# OPENAI_API_KEY or GEMINI_API_KEY is REQUIRED: without a valid key the wren-ai-service pod will not start
# You must update PG_URL, otherwise wren-ui will not work

# MODIFY/GENERATE values of secret and apply kubectl command to create secret (recommended for production)

# Generate secure passwords
OPENAI_API_KEY=<Paste OPENAI_API_KEY here>
PG_USERNAME=wrenai
PG_PASSWORD=$(openssl rand -base64 32)
PG_ADMIN_PASSWORD=$(openssl rand -base64 32)
PG_URL=postgres://wrenai-user:wrenai-pass@wren-postgresql:5432/wrenai
LANGFUSE_PUBLIC_KEY=<Paste LANGFUSE_PUBLIC_KEY here>
LANGFUSE_SECRET_KEY=<Paste LANGFUSE_SECRET_KEY here>
POSTHOG_API_KEY=<Paste POSTHOG_API_KEY here>
USER_UUID=$(openssl rand -base64 32)
Comment on lines +32 to +43
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Standardize PostgreSQL credentials and PG_URL; fix mismatch with examples.

Variables (PG_USERNAME/PG_PASSWORD) don’t match PG_URL (wrenai-user:wrenai-pass). Also the bullet claims both creds are “postgres.” This will break connections.

Apply:

-# Generate secure passwords
-OPENAI_API_KEY=<Paste OPENAI_API_KEY here>
-PG_USERNAME=wrenai
-PG_PASSWORD=$(openssl rand -base64 32)
-PG_ADMIN_PASSWORD=$(openssl rand -base64 32)
-PG_URL=postgres://wrenai-user:wrenai-pass@wren-postgresql:5432/wrenai
+# Generate secrets (sample: app user + admin user)
+OPENAI_API_KEY=<YOUR_OPENAI_API_KEY>
+PG_USERNAME=wrenai_user
+PG_PASSWORD=$(openssl rand -base64 32)
+PG_ADMIN_PASSWORD=$(openssl rand -base64 32)
+# Build PG_URL from variables to avoid drift
+PG_URL="postgres://${PG_USERNAME}:${PG_PASSWORD}@wren-postgresql:5432/wrenai"
 LANGFUSE_PUBLIC_KEY=<Paste LANGFUSE_PUBLIC_KEY here>
 LANGFUSE_SECRET_KEY=<Paste LANGFUSE_SECRET_KEY here>
 POSTHOG_API_KEY=<Paste POSTHOG_API_KEY here>
 USER_UUID=$(openssl rand -base64 32)
-Example: `PG_URL: "postgres://wrenai-user:wrenai-pass@wren-postgresql:5432/wrenai"`
+Example: `PG_URL: "postgres://<DB_USER>:<DB_PASSWORD>@wren-postgresql:5432/wrenai"`
 - `postgres://`        This is the protocol. It tells the system that you’re connecting to a PostgreSQL database.
-- `wrenai-user:wrenai-pass`  These are the username(first) and password(second) for the database respectively, separated by a colon. In this case, both the username and password are “postgres”.
+- `<DB_USER>:<DB_PASSWORD>`  Username (first) and password (second) separated by a colon.
 - `@wren-postgresql`   This is the hostname of the database server. "wren-postgresql" means the database server is running in a Kubernetes cluster and it is named "wren-postgresql" in the *same* namespace. If you are using another namespace you must provide the full hostname, example: `wren-postgresql.wren.svc.cluster.local`, "wren" is the namespace name, "svc.cluster.local" is the default domain name for Kubernetes services no need to change it.
 - `:5432`              This is the port number. PostgreSQL servers listen on port 5432 by default.
-- `/wrenai`          This is the name of the database you’re connecting to. In this case, the database name is `wrenai`. It can be found in the helm values file in the auth.database parameter.
+- `/wrenai`            Database name. See the Helm values under the PostgreSQL subchart (auth.database).

Also applies to: 79-85

🤖 Prompt for AI Agents
deployment/helm-chart/README.md lines 32-43 (also apply same fix at 79-85):
PG_USERNAME/PG_PASSWORD values do not match the hardcoded credentials in PG_URL
and the doc wrongly states both creds are “postgres”; update the README so
PG_URL is constructed from the PG_USERNAME and PG_PASSWORD variables (remove the
hardcoded wrenai-user:wrenai-pass), ensure the example credentials and
descriptive bullet correctly reflect the actual variable names/values, and
mirror these same corrections in the section at lines 79-85.


kubectl create secret generic wren-secret \
--from-literal=OPENAI_API_KEY=$OPENAI_API_KEY \
--from-literal=PG_USERNAME=$PG_USERNAME \
--from-literal=PG_PASSWORD=$PG_PASSWORD \
--from-literal=PG_ADMIN_PASSWORD=$PG_ADMIN_PASSWORD \
--from-literal=PG_URL=$PG_URL \
--from-literal=LANGFUSE_PUBLIC_KEY=$LANGFUSE_PUBLIC_KEY \
--from-literal=LANGFUSE_SECRET_KEY=$LANGFUSE_SECRET_KEY \
--from-literal=POSTHOG_API_KEY=$POSTHOG_API_KEY \
--from-literal=USER_UUID=$USER_UUID \
-n wren


# Download Wren AI dependency charts like Qdrant or postgresql
helm dependency build ./deployment/helm-chart

# Deploy Wren AI with Helm
helm upgrade --install wrenai ./deployment/helm-chart \
--namespace wren \
-f deployment/helm/values.yaml \

kubectl get pods -n wren
```

### Notes on Helm:
- `deployment/helm/values.yaml` is the main file responsible for versions of other apps such as Qdrant and PostgreSQL, version of your Wren AI app. It also combines resourses from the manifest such as ConfigMaps, Deployments, and Services. And example Ingress and Secrets.
- `deployment/helm/template` is the manifests folder that contains the core Wren AI manifest templates, its less likely you need to modify them, but check just in case
- `deployment/helm/charts` is directory contains any dependent Helm charts (subcharts) required by Wren AI, such as PostgreSQL or Qdrant. These dependencies are either added manually or using `helm dependency add`, and they are used to deploy third-party services alongside Wren AI.
- `deployment/helm/Chart.yaml` This file defines the metadata for the Helm chart used to deploy Wren AI. It includes the chart name, version, application version, dependencies and a description. Helm uses this file to identify and manage the chart during installation and upgrades.

#### Wren-UI Database
Starting with wren-ui version 0.6.0 by default the postgres database is used for wren-ui in this helm chart and will be installed in the same namespace as wren-ai.
- `postgres`: Database that will be installed in the same namespace as wren-ai. You *must* update `PG_URL` in the Secret manifest.

Example: `PG_URL: "postgres://wrenai-user:wrenai-pass@wren-postgresql:5432/wrenai"`
- `postgres://` This is the protocol. It tells the system that you’re connecting to a PostgreSQL database.
- `wrenai-user:wrenai-pass` These are the username(first) and password(second) for the database respectively, separated by a colon. In this case, both the username and password are “postgres”.
- `@wren-postgresql` This is the hostname of the database server. "wren-postgresql" means the database server is running in a Kubernetes cluster and it is named "wren-postgresql" in the *same* namespace. If you are using another namespace you must provide the full hostname, example: `wren-postgresql.wrenai.svc.cluster.local`, "wrenai" is the namespace name, "svc.cluster.local" is the default domain name for Kubernetes services no need to change it.
- `:5432` This is the port number. PostgreSQL servers listen on port 5432 by default.
- `/wrenai` This is the name of the database you’re connecting to. In this case, the database name is `wrenai`. It can be found in the helm values file in the auth.database parameter.

# Minikube
Prepare your k8s environment. Then use the `Steps to deploy` section to deploy Wren AI app into your k8s.
```shell
minikube start
minikube addons enable ingress
minikube addons enable metallb
minikube kubectl -- get nodes
minikube kubectl -- get pods -A

minikube update-context
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm install external-dns bitnami/external-dns
helm install \
external-dns bitnami/external-dns \
--namespace external-dns \
--version 7.5.2 \
--create-namespace \
--set installCRDs=true
kubectl get pods -n external-dns

helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install \
cert-manager jetstack/cert-manager \
--namespace cert-manager \
--version v1.13.6 \
--create-namespace \
--set installCRDs=true
kubectl get pods -n cert-manager

##########
# Use the `Steps to deploy` section to continue as you would on a production k8s cluster.
```

# GitOps Patches
In the [patches](./patches) folder you can find usefull kustomization examples files if you wish to use existing official kustomization directly from this repo as a base kustomization layer and only customize some values. It can be usefull for you GitOps workflow and can be used in conjunction with FluxCD or ArgoCD.
62 changes: 62 additions & 0 deletions deployment/helm-chart/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "wren-ai.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "wren-ai.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}

{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "wren-ai.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Common labels
*/}}
{{- define "wren-ai.labels" -}}
helm.sh/chart: {{ include "wren-ai.chart" . }}
{{ include "wren-ai.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

{{/*
Selector labels
*/}}
{{- define "wren-ai.selectorLabels" -}}
app.kubernetes.io/name: {{ include "wren-ai.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

{{/*
Return the secret name, using existingSecretName if specified, else default to <fullname>-secret
*/}}
{{- define "wren-ai.secretName" -}}
{{- if .Values.secrets.useExistingSecret -}}
{{- .Values.secrets.existingSecretName -}}
{{- else -}}
{{- include "wren-ai.fullname" . }}-secret
{{- end -}}
{{- end -}}
118 changes: 118 additions & 0 deletions deployment/helm-chart/templates/ai-service-deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
{{- $secretName := include "wren-ai.secretName" . }}
apiVersion: apps/v1
Comment on lines +1 to +2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Insert a YAML document start to silence linter syntax error

YAMLlint flags a “syntax error: expected the node content, but found ‘-’” on line 1.
Add an explicit document delimiter/blank line after the local template assignment so the rendered YAML starts cleanly:

{{- $secretName := include "wren-ai.secretName" . }}
+
+---
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{{- $secretName := include "wren-ai.secretName" . }}
apiVersion: apps/v1
{{- $secretName := include "wren-ai.secretName" . }}
---
apiVersion: apps/v1
🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

🤖 Prompt for AI Agents
In deployment/helm-chart/templates/ai-service-deployment.yaml at lines 1 to 2,
the YAML linter reports a syntax error due to the local template assignment line
not being separated from the YAML content. Fix this by adding a YAML document
start delimiter (---) or a blank line immediately after the local template
assignment line to ensure the rendered YAML begins cleanly and resolves the
linter syntax error.

kind: Deployment
metadata:
name: {{ include "wren-ai.fullname" . }}-ai-service
labels:
{{- include "wren-ai.labels" . | nindent 4 }}
app.kubernetes.io/component: ai-service
spec:
replicas: {{ default 1 .Values.aiService.replicaCount }}
selector:
matchLabels:
{{- include "wren-ai.selectorLabels" . | nindent 6 }}
app.kubernetes.io/component: ai-service
template:
metadata:
labels:
{{- include "wren-ai.selectorLabels" . | nindent 8 }}
app.kubernetes.io/component: ai-service
spec:
{{- with .Values.aiService.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.aiService.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.aiService.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: wren-ai-service
image: "{{ .Values.aiService.image.repository }}:{{ .Values.aiService.image.tag | default .Values.global.versions.aiService}}"
imagePullPolicy: {{ .Values.aiService.image.pullPolicy }}
volumeMounts:
- name: config-volume
mountPath: /app/data
env:
- name: WREN_AI_SERVICE_PORT
value: {{ .Values.config.ports.aiService | quote }}
{{- if .Values.secrets.createFromValues }}
{{- if .Values.secrets.values.OPENAI_API_KEY }}
- name: OPENAI_API_KEY
valueFrom:
secretKeyRef:
name: {{ $secretName }}
key: OPENAI_API_KEY
{{- else if .Values.secrets.values.GEMINI_API_KEY }}
- name: GEMINI_API_KEY
valueFrom:
secretKeyRef:
name: {{ $secretName }}
key: GEMINI_API_KEY
{{- end }}
{{- else }}
- name: OPENAI_API_KEY
valueFrom:
secretKeyRef:
name: {{ $secretName }}
key: OPENAI_API_KEY
optional: true
- name: GEMINI_API_KEY
valueFrom:
secretKeyRef:
name: {{ $secretName }}
key: GEMINI_API_KEY
optional: true
{{- end }}
- name: QDRANT_HOST
value: {{ default (printf "%s-qdrant" .Release.Name) .Values.config.documentStore.qdrantHost | quote }}
- name: LOGGING_LEVEL
value: {{ .Values.config.logging.level | quote }}
- name: WREN_UI_ENDPOINT
value: {{ .Values.config.endpoints.ui | quote }}
- name: PYTHONUNBUFFERED
value: {{ .Values.aiService.env.pythonUnbuffered | quote }}
{{- if .Values.pipeline.settings.langfuseEnable }}
- name: LANGFUSE_PUBLIC_KEY
valueFrom:
secretKeyRef:
name: {{ $secretName }}
key: LANGFUSE_PUBLIC_KEY
- name: LANGFUSE_SECRET_KEY
valueFrom:
secretKeyRef:
name: {{ $secretName }}
key: LANGFUSE_SECRET_KEY
- name: LANGFUSE_HOST
value: {{ .Values.pipeline.settings.langfuseHost | quote }}
{{- end }}
- name: CONFIG_PATH
value: {{ .Values.aiService.env.configPath | quote }}
{{- if .Values.config.telemetry.enabled }}
- name: POSTHOG_API_KEY
valueFrom:
secretKeyRef:
name: {{ $secretName }}
key: POSTHOG_API_KEY
- name: POSTHOG_HOST
value: {{ .Values.config.telemetry.posthogHost | quote }}
{{- end }}
ports:
- name: http
containerPort: {{ .Values.config.ports.aiService }}
protocol: TCP
{{- with .Values.aiService.resources }}
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
volumes:
- name: config-volume
configMap:
name: {{ include "wren-ai.fullname" . }}-ai-service-config
items:
- key: config.yaml
path: config.yaml
Loading