Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions Chart.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
apiVersion: v2
name: typesense
description: >-
Deploy Typesense search engine on Kubernetes with Raft-based HA clustering, Prometheus metrics, and Gateway API support. This chart is not officially maintained by or affiliated with the Typesense project.
Deploy Typesense search engine on Kubernetes with Raft-based HA clustering,
Prometheus metrics, and Gateway API support. This chart is not officially
maintained by or affiliated with the Typesense project.
type: application
version: 1.1.0
version: 1.1.1
appVersion: "30.1"
icon: https://typesense.org/typesense-logo.svg
home: https://github.com/hackthebox/typesense-helm
Expand Down Expand Up @@ -36,5 +38,9 @@ annotations:
- name: metrics-exporter
image: imatefx/typesense-prometheus-exporter:v0.1.5
artifacthub.io/changes: |
- kind: added
description: Initial open-source release
- kind: fixed
description: "liveness probe default changed to tcpSocket to prevent restart loops during Raft catch-up"
- kind: changed
description: "probe type is now controlled via .type field (httpGet or tcpSocket) to avoid Helm merge producing multiple handlers"
- kind: changed
description: "default CPU request set to 2000m per Typesense minimum requirements"
32 changes: 22 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# typesense

![Version: 1.1.0](https://img.shields.io/badge/Version-1.1.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 30.1](https://img.shields.io/badge/AppVersion-30.1-informational?style=flat-square)
![Version: 1.1.1](https://img.shields.io/badge/Version-1.1.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 30.1](https://img.shields.io/badge/AppVersion-30.1-informational?style=flat-square)

[![Artifact Hub](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/typesense)](https://artifacthub.io/packages/search?repo=typesense)

Expand Down Expand Up @@ -233,9 +233,13 @@ storage:
| ingress.enabled | bool | `false` | Enable or disable Ingress for the application |
| ingress.hosts | list | `[]` | List of hostnames the Ingress will route traffic for |
| ingress.prefix | string | `"/"` | The URL path prefix for the application |
| livenessProbe.failureThreshold | int | `2` | Number of failed liveness checks before restarting the container |
| livenessProbe.httpGet | object | `{"path":"/health","port":"http"}` | HTTP GET path and port to check Typesense health for liveness |
| livenessProbe.periodSeconds | int | `10` | Period (in seconds) to perform the liveness check |
| livenessProbe.failureThreshold | int | `6` | Number of failed liveness checks before restarting the container |
| livenessProbe.httpGet.path | string | `"/health"` | |
| livenessProbe.httpGet.port | string | `"http"` | |
| livenessProbe.periodSeconds | int | `20` | Period (in seconds) to perform the liveness check |
| livenessProbe.tcpSocket.port | string | `"http"` | |
| livenessProbe.timeoutSeconds | int | `3` | |
| livenessProbe.type | string | `"tcpSocket"` | Probe type: 'tcpSocket' or 'httpGet'. Default is tcpSocket to check only that the process is alive and listening. Avoid httpGet /health for liveness: Typesense returns 503 when the write queue exceeds --healthy-write-lag (default 500), which occurs normally during Raft catch-up after a restart, causing a liveness-triggered restart loop that prevents the cluster from ever recovering. |
| metrics.enabled | bool | `false` | Enable Prometheus metrics sidecar |
| metrics.image.pullPolicy | string | `"IfNotPresent"` | Image pull policy for metrics exporter |
| metrics.image.repository | string | `"imatefx/typesense-prometheus-exporter"` | Metrics exporter image repository |
Expand All @@ -255,11 +259,15 @@ storage:
| podSecurityContext.runAsGroup | int | `3000` | Group ID for running the Typesense process |
| podSecurityContext.runAsNonRoot | bool | `true` | Ensure the container does not run as root |
| podSecurityContext.runAsUser | int | `10000` | User ID for running the Typesense process |
| readinessProbe.failureThreshold | int | `3` | Number of failed readiness checks before marking the pod as unready |
| readinessProbe.httpGet | object | `{"path":"/health","port":"http"}` | HTTP GET path and port to check Typesense readiness |
| readinessProbe.periodSeconds | int | `5` | Period (in seconds) to perform the readiness check |
| readinessProbe.failureThreshold | int | `12` | Number of failed readiness checks before marking the pod as unready |
| readinessProbe.httpGet.path | string | `"/health"` | |
| readinessProbe.httpGet.port | string | `"http"` | |
| readinessProbe.periodSeconds | int | `10` | Period (in seconds) to perform the readiness check |
| readinessProbe.tcpSocket.port | string | `"http"` | |
| readinessProbe.timeoutSeconds | int | `3` | |
| readinessProbe.type | string | `"httpGet"` | Probe type: 'httpGet' or 'tcpSocket' |
| replicaCount | int | `3` | Number of replicas for the Typesense deployment |
| resources | object | `{}` | Resource requests and limits for the Typesense container |
| resources | object | `{"requests":{"cpu":"2000m"}}` | Resource requests and limits for the Typesense container. Typesense requires at least 2 vCPUs to operate correctly. No CPU limit is set by default to avoid throttling during indexing and Raft catch-up. |
| secrets.externalSecret.enabled | bool | `false` | Enable or disable ExternalSecret creation (requires external-secrets operator) |
| secrets.externalSecret.extractKey | string | `""` | The key path to extract secrets from |
| secrets.externalSecret.storeName | string | `""` | The name of the ClusterSecretStore or SecretStore to use |
Expand All @@ -274,9 +282,13 @@ storage:
| serviceAccount.automountServiceAccountToken | bool | `false` | Whether to automount the ServiceAccount token |
| serviceAccount.create | bool | `true` | Whether to create a ServiceAccount |
| serviceAccount.name | string | `""` | Name of the ServiceAccount. Defaults to fullname |
| startupProbe.failureThreshold | int | `10` | Number of failed startup checks before marking the container as unhealthy |
| startupProbe.httpGet | object | `{"path":"/health","port":"http"}` | HTTP GET path and port to check Typesense health for startup |
| startupProbe.failureThreshold | int | `60` | Number of failed startup checks before marking the container as unhealthy |
| startupProbe.httpGet.path | string | `"/health"` | |
| startupProbe.httpGet.port | string | `"http"` | |
| startupProbe.periodSeconds | int | `10` | Period (in seconds) to perform the startup check |
| startupProbe.tcpSocket.port | string | `"http"` | |
| startupProbe.timeoutSeconds | int | `3` | |
| startupProbe.type | string | `"httpGet"` | Probe type: 'httpGet' or 'tcpSocket' |
| storage.className | string | `nil` | Storage class to use for Persistent Volume Claims (PVC) |
| storage.size | string | `"10Gi"` | Size of the persistent storage volume (e.g., 10Gi) |
| terminationGracePeriodSeconds | int | `300` | Termination grace period in seconds. Typesense recommends 300s to allow graceful shutdown. |
Expand Down
25 changes: 25 additions & 0 deletions templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,31 @@ Create the name of the service account to use
{{- end }}
{{- end }}

{{/*
Render a probe with a single handler selected by .type (httpGet or tcpSocket).
This avoids Helm's map-merge producing both handlers simultaneously when users
override just the type in their values, which Kubernetes rejects.
*/}}
{{- define "typesense.probe" -}}
{{- $p := . -}}
{{- if eq $p.type "tcpSocket" }}
tcpSocket: {{- toYaml $p.tcpSocket | nindent 2 }}
{{- else }}
httpGet: {{- toYaml $p.httpGet | nindent 2 }}
{{- end }}
failureThreshold: {{ $p.failureThreshold }}
periodSeconds: {{ $p.periodSeconds }}
{{- with $p.timeoutSeconds }}
timeoutSeconds: {{ . }}
{{- end }}
{{- with $p.successThreshold }}
successThreshold: {{ . }}
{{- end }}
{{- with $p.initialDelaySeconds }}
initialDelaySeconds: {{ . }}
{{- end }}
{{- end }}

{{/*
Create the nodeslist
*/}}
Expand Down
6 changes: 3 additions & 3 deletions templates/statefulset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,9 @@ spec:
containerPort: {{ .Values.service.port }}
- name: tcp-peering
containerPort: 8107
startupProbe: {{- toYaml .Values.startupProbe | nindent 12 }}
livenessProbe: {{- toYaml .Values.livenessProbe | nindent 12 }}
readinessProbe: {{- toYaml .Values.readinessProbe | nindent 12 }}
startupProbe: {{- include "typesense.probe" .Values.startupProbe | nindent 12 }}
livenessProbe: {{- include "typesense.probe" .Values.livenessProbe | nindent 12 }}
readinessProbe: {{- include "typesense.probe" .Values.readinessProbe | nindent 12 }}
resources: {{- toYaml .Values.resources | nindent 12 }}
volumeMounts:
- name: nodeslist
Expand Down
16 changes: 9 additions & 7 deletions tests/statefulset_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,20 @@ tests:
- equal:
path: .spec.template.spec.containers[0].startupProbe
value:
failureThreshold: 10
failureThreshold: 60
httpGet:
path: /health
port: http
periodSeconds: 10
timeoutSeconds: 3
- equal:
path: .spec.template.spec.containers[0].livenessProbe
value:
failureThreshold: 2
httpGet:
path: /health
failureThreshold: 6
tcpSocket:
port: http
periodSeconds: 10
periodSeconds: 20
timeoutSeconds: 3
- notExists:
path: .spec.volumeClaimTemplates[0].spec.storageClassName
- equal:
Expand Down Expand Up @@ -287,11 +288,12 @@ tests:
- equal:
path: .spec.template.spec.containers[0].readinessProbe
value:
failureThreshold: 3
failureThreshold: 12
httpGet:
path: /health
port: http
periodSeconds: 5
periodSeconds: 10
timeoutSeconds: 3
- it: should render default anti-affinity but not tolerations or topologySpreadConstraints when empty
asserts:
- notFailedTemplate: {}
Expand Down
32 changes: 22 additions & 10 deletions values.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# typesense

![Version: 1.1.0](https://img.shields.io/badge/Version-1.1.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 30.1](https://img.shields.io/badge/AppVersion-30.1-informational?style=flat-square)
![Version: 1.1.1](https://img.shields.io/badge/Version-1.1.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 30.1](https://img.shields.io/badge/AppVersion-30.1-informational?style=flat-square)

[![Artifact Hub](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/typesense)](https://artifacthub.io/packages/search?repo=typesense)

Expand Down Expand Up @@ -233,9 +233,13 @@ storage:
| ingress.enabled | bool | `false` | Enable or disable Ingress for the application |
| ingress.hosts | list | `[]` | List of hostnames the Ingress will route traffic for |
| ingress.prefix | string | `"/"` | The URL path prefix for the application |
| livenessProbe.failureThreshold | int | `2` | Number of failed liveness checks before restarting the container |
| livenessProbe.httpGet | object | `{"path":"/health","port":"http"}` | HTTP GET path and port to check Typesense health for liveness |
| livenessProbe.periodSeconds | int | `10` | Period (in seconds) to perform the liveness check |
| livenessProbe.failureThreshold | int | `6` | Number of failed liveness checks before restarting the container |
| livenessProbe.httpGet.path | string | `"/health"` | |
| livenessProbe.httpGet.port | string | `"http"` | |
| livenessProbe.periodSeconds | int | `20` | Period (in seconds) to perform the liveness check |
| livenessProbe.tcpSocket.port | string | `"http"` | |
| livenessProbe.timeoutSeconds | int | `3` | |
| livenessProbe.type | string | `"tcpSocket"` | Probe type: 'tcpSocket' or 'httpGet'. Default is tcpSocket to check only that the process is alive and listening. Avoid httpGet /health for liveness: Typesense returns 503 when the write queue exceeds --healthy-write-lag (default 500), which occurs normally during Raft catch-up after a restart, causing a liveness-triggered restart loop that prevents the cluster from ever recovering. |
| metrics.enabled | bool | `false` | Enable Prometheus metrics sidecar |
| metrics.image.pullPolicy | string | `"IfNotPresent"` | Image pull policy for metrics exporter |
| metrics.image.repository | string | `"imatefx/typesense-prometheus-exporter"` | Metrics exporter image repository |
Expand All @@ -255,11 +259,15 @@ storage:
| podSecurityContext.runAsGroup | int | `3000` | Group ID for running the Typesense process |
| podSecurityContext.runAsNonRoot | bool | `true` | Ensure the container does not run as root |
| podSecurityContext.runAsUser | int | `10000` | User ID for running the Typesense process |
| readinessProbe.failureThreshold | int | `3` | Number of failed readiness checks before marking the pod as unready |
| readinessProbe.httpGet | object | `{"path":"/health","port":"http"}` | HTTP GET path and port to check Typesense readiness |
| readinessProbe.periodSeconds | int | `5` | Period (in seconds) to perform the readiness check |
| readinessProbe.failureThreshold | int | `12` | Number of failed readiness checks before marking the pod as unready |
| readinessProbe.httpGet.path | string | `"/health"` | |
| readinessProbe.httpGet.port | string | `"http"` | |
| readinessProbe.periodSeconds | int | `10` | Period (in seconds) to perform the readiness check |
| readinessProbe.tcpSocket.port | string | `"http"` | |
| readinessProbe.timeoutSeconds | int | `3` | |
| readinessProbe.type | string | `"httpGet"` | Probe type: 'httpGet' or 'tcpSocket' |
| replicaCount | int | `3` | Number of replicas for the Typesense deployment |
| resources | object | `{}` | Resource requests and limits for the Typesense container |
| resources | object | `{"requests":{"cpu":"2000m"}}` | Resource requests and limits for the Typesense container. Typesense requires at least 2 vCPUs to operate correctly. No CPU limit is set by default to avoid throttling during indexing and Raft catch-up. |
| secrets.externalSecret.enabled | bool | `false` | Enable or disable ExternalSecret creation (requires external-secrets operator) |
| secrets.externalSecret.extractKey | string | `""` | The key path to extract secrets from |
| secrets.externalSecret.storeName | string | `""` | The name of the ClusterSecretStore or SecretStore to use |
Expand All @@ -274,9 +282,13 @@ storage:
| serviceAccount.automountServiceAccountToken | bool | `false` | Whether to automount the ServiceAccount token |
| serviceAccount.create | bool | `true` | Whether to create a ServiceAccount |
| serviceAccount.name | string | `""` | Name of the ServiceAccount. Defaults to fullname |
| startupProbe.failureThreshold | int | `10` | Number of failed startup checks before marking the container as unhealthy |
| startupProbe.httpGet | object | `{"path":"/health","port":"http"}` | HTTP GET path and port to check Typesense health for startup |
| startupProbe.failureThreshold | int | `60` | Number of failed startup checks before marking the container as unhealthy |
| startupProbe.httpGet.path | string | `"/health"` | |
| startupProbe.httpGet.port | string | `"http"` | |
| startupProbe.periodSeconds | int | `10` | Period (in seconds) to perform the startup check |
| startupProbe.tcpSocket.port | string | `"http"` | |
| startupProbe.timeoutSeconds | int | `3` | |
| startupProbe.type | string | `"httpGet"` | Probe type: 'httpGet' or 'tcpSocket' |
| storage.className | string | `nil` | Storage class to use for Persistent Volume Claims (PVC) |
| storage.size | string | `"10Gi"` | Size of the persistent storage volume (e.g., 10Gi) |
| terminationGracePeriodSeconds | int | `300` | Termination grace period in seconds. Typesense recommends 300s to allow graceful shutdown. |
Expand Down
41 changes: 31 additions & 10 deletions values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -119,38 +119,59 @@ gateway:
namespace: "istio-system"
extras: []

# -- Resource requests and limits for the Typesense container
resources: {}
# -- Resource requests and limits for the Typesense container.
# Typesense requires at least 2 vCPUs to operate correctly. No CPU limit is
# set by default to avoid throttling during indexing and Raft catch-up.
resources:
requests:
cpu: 2000m

livenessProbe:
# -- HTTP GET path and port to check Typesense health for liveness
# -- Probe type: 'tcpSocket' or 'httpGet'.
# Default is tcpSocket to check only that the process is alive and listening.
# Avoid httpGet /health for liveness: Typesense returns 503 when the write
# queue exceeds --healthy-write-lag (default 500), which occurs normally
# during Raft catch-up after a restart, causing a liveness-triggered restart
# loop that prevents the cluster from ever recovering.
type: tcpSocket
httpGet:
path: /health
port: http
tcpSocket:
port: http
# -- Number of failed liveness checks before restarting the container
failureThreshold: 2
failureThreshold: 6
# -- Period (in seconds) to perform the liveness check
periodSeconds: 10
periodSeconds: 20
timeoutSeconds: 3

startupProbe:
# -- HTTP GET path and port to check Typesense health for startup
# -- Probe type: 'httpGet' or 'tcpSocket'
type: httpGet
httpGet:
path: /health
port: http
tcpSocket:
port: http
# -- Number of failed startup checks before marking the container as unhealthy
failureThreshold: 10
failureThreshold: 60
# -- Period (in seconds) to perform the startup check
periodSeconds: 10
timeoutSeconds: 3

readinessProbe:
# -- HTTP GET path and port to check Typesense readiness
# -- Probe type: 'httpGet' or 'tcpSocket'
type: httpGet
httpGet:
path: /health
port: http
tcpSocket:
port: http
# -- Period (in seconds) to perform the readiness check
periodSeconds: 5
periodSeconds: 10
# -- Number of failed readiness checks before marking the pod as unready
failureThreshold: 3
failureThreshold: 12
timeoutSeconds: 3

# -- Node selector to schedule pods on specific nodes (optional)
nodeSelector: {}
Expand Down
Loading