diff --git a/charts/currents/Chart.yaml b/charts/currents/Chart.yaml index 6a362bf..677a933 100644 --- a/charts/currents/Chart.yaml +++ b/charts/currents/Chart.yaml @@ -5,7 +5,7 @@ home: https://currents.dev type: application # The chart version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.7.5 +version: 0.8.0 # Version number of the application being deployed. # Versions are not expected to follow Semantic Versioning. They should reflect the version the application is using. appVersion: "2026-07-26-004" diff --git a/charts/currents/templates/_common.tpl b/charts/currents/templates/_common.tpl index 349fe2c..7946123 100644 --- a/charts/currents/templates/_common.tpl +++ b/charts/currents/templates/_common.tpl @@ -92,10 +92,26 @@ Create the name of the service account to use {{- end -}} {{- define "currents.connectionConfigEnv" -}} +{{- $redis := .Values.currents.redis }} +{{- if $redis.connection.secretName }} - name: REDIS_URI - value: {{ printf "redis://%s:6379" (tpl .Values.currents.redis.host .) }} + valueFrom: + secretKeyRef: + name: {{ $redis.connection.secretName }} + key: {{ $redis.connection.key }} +- name: REDIS_URI_SLAVE + valueFrom: + secretKeyRef: + name: {{ $redis.connection.secretName }} + key: {{ $redis.connection.readerKey | default $redis.connection.key }} +{{- else }} +{{- $scheme := ternary "rediss" "redis" $redis.tls.enabled }} +{{- $reader := default $redis.host $redis.readerHost }} +- name: REDIS_URI + value: {{ printf "%s://%s:%v" $scheme (tpl $redis.host .) $redis.port | quote }} - name: REDIS_URI_SLAVE - value: {{ printf "redis://%s:6379" (tpl .Values.currents.redis.host .) }} + value: {{ printf "%s://%s:%v" $scheme (tpl $reader .) $redis.port | quote }} +{{- end }} {{- if .Values.currents.mongoConnection.secretName }} - name: MONGODB_URI valueFrom: diff --git a/charts/currents/values.yaml b/charts/currents/values.yaml index 6038175..b46505e 100644 --- a/charts/currents/values.yaml +++ b/charts/currents/values.yaml @@ -122,9 +122,30 @@ currents: # @section -- Frequently Used key: token redis: - # -- (tpl) set the redis hostname to talk to + # -- (tpl) set the redis hostname to talk to. The default names the bundled Redis's service, + # which only exists when `redis.enabled` is true — point this at your own server otherwise. # @default -- `{{ .Release.Name }}-redis-master` host: "{{ .Release.Name }}-redis-master" + # -- (tpl) hostname for read-only traffic. A managed Redis usually publishes a separate + # reader endpoint; leaving this empty sends reads to `host`, which is the primary. + readerHost: "" + # -- The port to connect on + port: 6379 + tls: + # -- Connect with `rediss://`. Set this for a managed Redis with encryption in transit. + enabled: false + # -- Read the connection URI from a K8s secret instead of composing it from the fields + # above. Needed for any Redis that requires credentials: the composed URI is rendered + # into the pod spec, so an AUTH token set that way would be readable by anyone who can + # describe a pod. Leave unset to use the bundled Redis. + # @section -- Frequently Used + connection: + # -- Secret holding the full URI, e.g. `rediss://:@host:6379` + secretName: "" + # -- Secret key for the primary URI + key: uri + # -- Secret key for the read-only URI. Defaults to `key` when unset. + readerKey: "" clickhouse: user: # -- The ClickHouse username to use diff --git a/docs/configuration.md b/docs/configuration.md index 3e33f82..47f4beb 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -1,6 +1,6 @@ # Configuration Reference -![Version: 0.7.5](https://img.shields.io/badge/Version-0.7.5-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 2026-07-26-004](https://img.shields.io/badge/AppVersion-2026--07--26--004-informational?style=flat-square) +![Version: 0.8.0](https://img.shields.io/badge/Version-0.8.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 2026-07-26-004](https://img.shields.io/badge/AppVersion-2026--07--26--004-informational?style=flat-square) ## Requirements @@ -46,6 +46,7 @@ The following table lists the configurable parameters of the `currents` chart an | currents.email.smtp.secretPasswordKey | string | `"password"` | The K8s secret key to use for the SMTP password | | currents.betterAuth.key | string | `"secret"` | The K8s secret key for the Better Auth secret | | currents.apiInternalToken.key | string | `"token"` | The K8s secret key to use for the internal API token | +| currents.redis.connection | object | `{"key":"uri","readerKey":"","secretName":""}` | Read the connection URI from a K8s secret instead of composing it from the fields above. Needed for any Redis that requires credentials: the composed URI is rendered into the pod spec, so an AUTH token set that way would be readable by anyone who can describe a pod. Leave unset to use the bundled Redis. | | currents.clickhouse.user.username | string | `"currents"` | The ClickHouse username to use | | currents.clickhouse.tls.enabled | bool | `true` | Whether to use TLS for the ClickHouse connection | | currents.objectStorage.secretIdKey | string | `"keyId"` | The K8s secret key to use for the object storage access key ID | @@ -101,7 +102,13 @@ The following table lists the configurable parameters of the `currents` chart an | currents.email.inviteBcc | string | `""` | BCC address for invitation emails | | currents.email.linksBaseUrl | string | `""` | Base URL for links in emails (defaults to APP_BASE_URL if empty) | | currents.ingress.enabled | bool | `false` | Whether to enable the both default ingresses (server, and director) | -| currents.redis.host | tpl | `{{ .Release.Name }}-redis-master` | set the redis hostname to talk to | +| currents.redis.host | tpl | `{{ .Release.Name }}-redis-master` | set the redis hostname to talk to. The default names the bundled Redis's service, which only exists when `redis.enabled` is true — point this at your own server otherwise. | +| currents.redis.readerHost | tpl | `""` | hostname for read-only traffic. A managed Redis usually publishes a separate reader endpoint; leaving this empty sends reads to `host`, which is the primary. | +| currents.redis.port | int | `6379` | The port to connect on | +| currents.redis.tls.enabled | bool | `false` | Connect with `rediss://`. Set this for a managed Redis with encryption in transit. | +| currents.redis.connection.secretName | string | `""` | Secret holding the full URI, e.g. `rediss://:@host:6379` | +| currents.redis.connection.key | string | `"uri"` | Secret key for the primary URI | +| currents.redis.connection.readerKey | string | `""` | Secret key for the read-only URI. Defaults to `key` when unset. | | currents.clickhouse.port | int | `8123` | The ClickHouse port to use | | currents.objectStorage.internalEndpoint | string | `""` | The object storage internal endpoint to use (for internal communication) | | currents.objectStorage.region | string | `""` | The region to use for the object storage | diff --git a/docs/eks/dependencies.md b/docs/eks/dependencies.md index a5137ab..b0c3410 100644 --- a/docs/eks/dependencies.md +++ b/docs/eks/dependencies.md @@ -100,6 +100,66 @@ This will setup a 1-node 1-shard ClickHouse Replicated Server (10Gb Storage) --set operator.enabled=false ``` +### Redis + +Redis is required, and the chart does not deploy one unless you ask it to. Pick one of: + +- **Bundled** — set `redis.enabled: true`, as the [quickstart](./quickstart.md) does. Convenient, + and usable in production, but it has no high availability during a version upgrade. +- **Your own** — leave `redis.enabled` at its default of `false` and point the chart at an + existing server, as below. This is the option to take if you already operate Redis, or would + rather not operate one at all. + +`currents.redis.host` defaults to the bundled Redis's service name, so it only resolves when +`redis.enabled` is `true`. Setting one without the other leaves the install pointed at a service +that was never deployed. + +**What your own Redis has to provide.** Currents stores orchestration state as JSON documents +and reads them from inside Lua scripts, so the server must support the `JSON.GET` / `JSON.SET` +commands. On ElastiCache that means **Redis 6.2.6 or newer, or Valkey**; older engines will start +the app but fail spec claiming under load. Run a real test run against it before cutting over, not +just a health check. + +Use a **replication group with a primary and a replica**, not cluster mode. Currents runs multi-key +Lua scripts, and cluster mode rejects those when the keys land in different slots. This is the +topology the hosted service runs. + +**Authentication is an AUTH token supplied in the URI.** IAM authentication is not supported — +the client takes a static credential and has nothing to refresh a short-lived one. + +1. Create the secret holding the connection URI. Keep the token here rather than in your values + file: a URI composed from plain values is rendered into the pod spec, where anyone who can + describe a pod can read it. + + ```sh + kubectl create secret generic currents-redis \ + --from-literal=uri="rediss://:@master..cache.amazonaws.com:6379" \ + --from-literal=readerUri="rediss://:@replica..cache.amazonaws.com:6379" + ``` + + `rediss://` selects encryption in transit. Use `redis://` only if the group has it disabled. + +2. Point the chart at it, leaving the bundled Redis off (set it explicitly if you previously + turned it on): + + ```yaml + redis: + enabled: false + + currents: + redis: + connection: + secretName: currents-redis + key: uri + readerKey: readerUri + ``` + + `readerKey` is optional. Without it, read-only traffic goes to the primary; with it, to the + reader endpoint. + +For a Redis that needs no credentials, `currents.redis.host`, `readerHost`, `port` and +`tls.enabled` compose the URI directly and no secret is required. + ### Object Storage (provider) Follow this step if you plan to use provider (S3, Cloudflare) object storage (recommended).