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
70 changes: 70 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,76 @@ s3:
prefix: "media/"
```

##### With Redis Cluster

Langfuse supports Redis Cluster mode for high-availability and scalability. Configure Redis in one of two ways:

**Standalone Mode (Default):**

```yaml
redis:
deploy: false # Set to false for external Redis
host: "my-redis.example.com"
port: 6379
auth:
password: "your-password"
```

**Cluster Mode:**

```yaml
redis:
deploy: false # Must be false - deployed Redis doesn't support cluster mode
cluster:
enabled: true
nodes:
- "redis-node-1:6379"
- "redis-node-2:6379"
- "redis-node-3:6379"
- "redis-node-4:6379"
- "redis-node-5:6379"
- "redis-node-6:6379"
auth:
password: "your-cluster-password"
```

**Redis Cluster with TLS:**

```yaml
redis:
deploy: false
cluster:
enabled: true
nodes:
- "redis-node-1:6379"
- "redis-node-2:6379"
- "redis-node-3:6379"
auth:
password: "your-cluster-password"
tls:
enabled: true
caPath: "/certs/ca.crt"
certPath: "/certs/client.crt"
keyPath: "/certs/client.key"
```

**AWS ElastiCache Example:**

For AWS ElastiCache Redis Cluster, use the configuration endpoint that automatically discovers all cluster nodes:

```yaml
redis:
deploy: false
cluster:
enabled: true
nodes:
- "clustercfg.my-redis-cluster.abc123.cache.amazonaws.com:6379"
auth:
password: "your-auth-token"
tls:
enabled: true
```

#### Use custom deployment strategy

```yaml
Expand Down
2 changes: 2 additions & 0 deletions charts/langfuse/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@ Open source LLM engineering platform - LLM observability, metrics, evaluations,
| redis.auth.existingSecretPasswordKey | string | `""` | The key in the existing secret that contains the password. |
| redis.auth.password | string | `""` | Configure the password by value or existing secret reference. Use URL-encoded passwords or avoid special characters in the password. |
| redis.auth.username | string | `"default"` | Username to use to connect to the redis database deployed with Langfuse. In case `redis.deploy` is set to `true`, the user will be created automatically. Set to null for an empty username in the connection string. |
| redis.cluster.enabled | bool | `false` | Set to `true` to enable Redis Cluster mode. When enabled, you must set `redis.deploy` to `false` and provide cluster nodes. |
| redis.cluster.nodes | list | `[]` | List of Redis cluster nodes in the format "host:port". Example: ["redis-1:6379", "redis-2:6379", "redis-3:6379"] |
| redis.deploy | bool | `true` | Enable valkey deployment (via Bitnami Helm Chart). If you want to use a Redis or Valkey server already deployed, set to false. |
| redis.host | string | `""` | Redis host to connect to. If redis.deploy is true, this will be set automatically based on the release name. |
| redis.image.repository | string | `"bitnamilegacy/valkey"` | Overwrite default repository of helm chart to point to non-paid bitnami images. |
Expand Down
29 changes: 29 additions & 0 deletions charts/langfuse/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,34 @@ Get value of a specific environment variable from additionalEnv if it exists
value: {{ required "Using an existing secret or redis.auth.password is required" .Values.redis.auth.password | quote }}
{{- end }}
{{- end }}
{{- if .Values.redis.cluster.enabled }}
{{- if not (include "langfuse.getEnvVar" (dict "env" $.Values.langfuse.additionalEnv "name" "REDIS_CLUSTER_NODES")) }}
- name: REDIS_CLUSTER_ENABLED
value: "true"
- name: REDIS_CLUSTER_NODES
value: {{ join "," .Values.redis.cluster.nodes | quote }}
{{- if or .Values.redis.auth.existingSecret .Values.redis.auth.password }}
- name: REDIS_AUTH
value: "$(REDIS_PASSWORD)"
{{- end }}
- name: REDIS_TLS_ENABLED
value: {{ .Values.redis.tls.enabled | quote }}
{{- if .Values.redis.tls.enabled }}
{{- if .Values.redis.tls.caPath }}
- name: REDIS_TLS_CA_PATH
value: {{ .Values.redis.tls.caPath | quote }}
{{- end }}
{{- if .Values.redis.tls.certPath }}
- name: REDIS_TLS_CERT_PATH
value: {{ .Values.redis.tls.certPath | quote }}
{{- end }}
{{- if .Values.redis.tls.keyPath }}
- name: REDIS_TLS_KEY_PATH
value: {{ .Values.redis.tls.keyPath | quote }}
{{- end }}
{{- end }}
{{- end }}
{{- else }}
{{- if not (include "langfuse.getEnvVar" (dict "env" $.Values.langfuse.additionalEnv "name" "REDIS_CONNECTION_STRING")) }}
- name: REDIS_TLS_ENABLED
value: {{ .Values.redis.tls.enabled | quote }}
Expand All @@ -329,6 +357,7 @@ Get value of a specific environment variable from additionalEnv if it exists
value: {{ .Values.redis.tls.keyPath | quote }}
{{- end }}
{{- end }}
{{- end }}
{{- end -}}


Expand Down
21 changes: 19 additions & 2 deletions charts/langfuse/templates/validations.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,25 @@
{{- fail "Langfuse requires valkey to be deployed with the `--maxmemory-policy noeviction` flag. Set redis.primary.extraFlags to include this flag to continue." -}}
{{- end -}}

{{- if and (not $.Values.redis.deploy) (not $.Values.redis.host) (not (include "langfuse.getEnvVar" (dict "env" $.Values.langfuse.additionalEnv "name" "REDIS_CONNECTION_STRING"))) -}}
{{- fail "Redis host must be configured when using an external Redis instance. Set redis.host to continue." -}}
{{- if and (not $.Values.redis.deploy) (not $.Values.redis.host) (not $.Values.redis.cluster.enabled) (not (include "langfuse.getEnvVar" (dict "env" $.Values.langfuse.additionalEnv "name" "REDIS_CONNECTION_STRING"))) -}}
{{- fail "Redis host must be configured when using an external Redis instance. Set redis.host or enable redis.cluster.enabled to continue." -}}
{{- end -}}

{{- if and $.Values.redis.host (include "langfuse.getEnvVar" (dict "env" $.Values.langfuse.additionalEnv "name" "REDIS_CONNECTION_STRING")) -}}
{{- fail "Only one of additionalEnv or the new structure can be configured. Set either redis configuration or langfuse.additionalEnv[name: REDIS_CONNECTION_STRING] to continue." -}}
{{- end -}}

# Validate Redis Cluster settings
{{- if and $.Values.redis.cluster.enabled (eq (len $.Values.redis.cluster.nodes) 0) (not (include "langfuse.getEnvVar" (dict "env" $.Values.langfuse.additionalEnv "name" "REDIS_CLUSTER_NODES"))) -}}
{{- fail "Redis cluster nodes must be configured when cluster mode is enabled. Set redis.cluster.nodes or langfuse.additionalEnv[name: REDIS_CLUSTER_NODES] to continue." -}}
{{- end -}}

{{- if and $.Values.redis.cluster.nodes (include "langfuse.getEnvVar" (dict "env" $.Values.langfuse.additionalEnv "name" "REDIS_CLUSTER_NODES")) -}}
{{- fail "Only one of additionalEnv or the new structure can be configured. Set either redis.cluster.nodes or langfuse.additionalEnv[name: REDIS_CLUSTER_NODES] to continue." -}}
{{- end -}}

{{- if and $.Values.redis.deploy $.Values.redis.cluster.enabled -}}
{{- fail "Redis cluster mode cannot be used with deployed Redis (redis.deploy: true). The deployed Redis is standalone/sentinel architecture. Set redis.deploy to false and configure external Redis cluster nodes to continue." -}}
{{- end -}}

# Validate S3 settings
Expand Down
Loading