Skip to content

Commit dcb5592

Browse files
committed
Merge remote-tracking branch 'origin/main' into samejr/task-landing-page-layout-improvements
2 parents 08b16d0 + cb9aefd commit dcb5592

14 files changed

Lines changed: 561 additions & 52 deletions

File tree

docs/self-hosting/docker.mdx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,17 @@ TRIGGER_IMAGE_TAG=v4.5.0
362362
363363
We patch the latest released version line only, so keep an eye on new releases to receive security fixes. See [Security & vulnerability reporting](/self-hosting/security).
364364
365+
You can also lock the versions of the bundled services, for example with `CLICKHOUSE_IMAGE_TAG`. If you do, or if you bring your own ClickHouse via `CLICKHOUSE_URL`, note that Trigger.dev requires ClickHouse 25.8 or newer.
366+
367+
<Note>
368+
The bundled ClickHouse now uses the official `clickhouse/clickhouse-server` image. Your existing
369+
data volume carries over automatically. If you previously pinned `CLICKHOUSE_IMAGE_TAG` to a
370+
Bitnami tag (for example `25.7.5-debian-12-r0`), update it to an official image tag such as
371+
`26.2` — Bitnami tags don't exist in the official repository. Note the switch is one-way: the
372+
official image takes ownership of the data files, so rolling back to the Bitnami image requires
373+
manually restoring their previous owner (`chown -R 1001:1001` on the volume).
374+
</Note>
375+
365376
<Note>
366377
Trigger.dev 4.5.0 is the last version we officially support for running v3 (SDK v3) tasks. If
367378
you still have v3 tasks, pin `TRIGGER_IMAGE_TAG` to exactly `v4.5.0` or [migrate to

docs/self-hosting/kubernetes.mdx

Lines changed: 93 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,56 @@ kubectl port-forward svc/trigger-webapp 3040:3030 -n trigger
8080
kubectl logs -n trigger deployment/trigger-webapp | grep -A1 "magic link"
8181
```
8282

83+
## Upgrading
84+
85+
`helm upgrade` keeps generated secrets, PVCs, and datastore volumes, so most upgrades need no preparation. These chart versions are the exceptions.
86+
87+
### 4.5.6: two new required secret keys
88+
89+
The webapp now reads `PROVIDER_SECRET` and `COORDINATOR_SECRET`. When you supply `secrets.existingSecret` the chart generates nothing and reads every key from your Secret, so both keys must exist there before you upgrade. Inline `secrets.*` values are ignored while `existingSecret` is set.
90+
91+
Add them with two fresh 32-character hex values:
92+
93+
```bash
94+
kubectl patch secret my-trigger-secrets -n trigger --type merge -p \
95+
"{\"stringData\":{\"PROVIDER_SECRET\":\"$(openssl rand -hex 16)\",\"COORDINATOR_SECRET\":\"$(openssl rand -hex 16)\"}}"
96+
```
97+
98+
The chart checks your Secret in a pre-upgrade hook and aborts with the list of missing keys, leaving the running release untouched. Without that check a missing key surfaces as a `CreateContainerConfigError` partway through the webapp rollout.
99+
100+
<Note>
101+
GitOps tools that render with `helm template` have no cluster access, so the check is
102+
skipped and a missing key still reaches the rollout. Verify the keys yourself before syncing.
103+
</Note>
104+
105+
### 4.5.6: ClickHouse credentials moved
106+
107+
The bundled ClickHouse password moved out of the subchart-generated Secret and into the chart-managed datastore Secret:
108+
109+
| | Up to 4.5.5 | 4.5.6 and later |
110+
| ------ | ---------------------- | --------------------------- |
111+
| Secret | `<release>-clickhouse` | `trigger-datastore` |
112+
| Key | `admin-password` | `clickhouse-admin-password` |
113+
114+
The webapp and the ClickHouse server both read the new location, so the upgrade itself needs no action. Repoint anything outside the chart that reads the old Secret — a maintenance CronJob, a Grafana datasource, an external secret sync:
115+
116+
```bash
117+
kubectl get secret trigger-datastore -n trigger \
118+
-o jsonpath='{.data.clickhouse-admin-password}' | base64 -d
119+
```
120+
121+
The same move applies to the bundled PostgreSQL (`postgres-password`) and MinIO (`minio-root-user`, `minio-root-password`).
122+
123+
### Bitnami ClickHouse to the official image
124+
125+
The bundled ClickHouse runs the official `clickhouse/clickhouse-server` image instead of the Bitnami subchart. The chart adopts your existing data volume automatically, with three caveats covered under [ClickHouse](#clickhouse) in external services: rendering without cluster access, pinned Bitnami image tags, and storage that doesn't support `fsGroup`.
126+
127+
<Note>
128+
The data volume is `ReadWriteOnce`, so during the upgrade the new ClickHouse pod may sit in
129+
`ContainerCreating` with a multi-attach warning for a minute while the old pod still holds the
130+
volume. This clears itself once the old pod is removed later in the same upgrade - don't abort.
131+
</Note>
132+
83133
## Configuration
84134

85135
Most values map directly to the environment variables documented in the [webapp](/self-hosting/env/webapp) and [supervisor](/self-hosting/env/supervisor) environment variable overview.
@@ -138,8 +188,9 @@ secrets:
138188
# - PROVIDER_SECRET
139189
# - COORDINATOR_SECRET
140190
# - MANAGED_WORKER_SECRET
141-
# - OBJECT_STORE_ACCESS_KEY_ID
142-
# - OBJECT_STORE_SECRET_ACCESS_KEY
191+
# Plus s3-auth-access-key-id and s3-auth-secret-access-key if you deploy the
192+
# bundled MinIO with s3.auth.existingSecret cleared. The chart lists any keys
193+
# it can't find and fails the install before touching a running release.
143194
secrets:
144195
enabled: false
145196
existingSecret: "your-existing-secret"
@@ -279,26 +330,64 @@ redis:
279330
280331
#### ClickHouse
281332
333+
<Note>Trigger.dev requires ClickHouse 25.8 or newer.</Note>
334+
335+
<Note>
336+
When upgrading from a chart version that bundled ClickHouse via the Bitnami subchart, the chart
337+
automatically adopts the existing data volume, so no manual migration is needed. If you render
338+
manifests without cluster access (for example with GitOps tools that use `helm template`), set
339+
`clickhouse.persistence.existingClaim` to the old PVC name
340+
(`data-<release>-clickhouse-shard0-0`) to keep your data — auto-detection can't run there, and
341+
skipping this starts ClickHouse on a fresh empty volume. If that happened, your old data is
342+
still on the old PVC: delete the ClickHouse StatefulSet with `--cascade=orphan` (its volume
343+
configuration is immutable), set `existingClaim`, and sync again. If you render without cluster
344+
access, pin `clickhouse.persistence.existingClaim` for good once the volume is adopted: a later
345+
render where the lookup can't see the PVC would otherwise try to re-add `volumeClaimTemplates`,
346+
which the API server rejects on an existing StatefulSet.
347+
</Note>
348+
349+
<Note>
350+
If you pinned `clickhouse.image` to a Bitnami repository or tag in your values, update it to
351+
the official `clickhouse/clickhouse-server` image — Bitnami tags don't exist there. The
352+
bundled ClickHouse is single-node: the old Bitnami subchart keys (`shards`, `replicaCount`,
353+
`keeper`) are no longer supported, so use an external ClickHouse for clustered setups.
354+
</Note>
355+
356+
<Note>
357+
When a volume is adopted from the Bitnami-based chart, a one-time init container fixes its
358+
ownership for the non-root ClickHouse server. This runs automatically on `helm upgrade` (and
359+
when you set `clickhouse.persistence.existingClaim`), so storage that doesn't support `fsGroup`
360+
ownership changes (NFS, hostPath, local-path) works without manual steps. Set
361+
`clickhouse.volumePermissions.enabled: true` to force it in other cases.
362+
</Note>
363+
282364
**Direct configuration:**
283365

284366
```yaml
285367
clickhouse:
286368
deploy: false
287369
external:
288370
host: "my-clickhouse.example.com"
289-
port: 8123
371+
httpPort: 8123
290372
username: "my-username"
291373
password: "my-password"
292374
```
293375

376+
<Note>
377+
An inline external `username`/`password` is percent-encoded into the connection URL for you, so
378+
store the **raw** value - special characters like `@ : / %` are handled automatically. If you
379+
previously percent-encoded the password by hand to work around this, switch back to the raw value.
380+
(Credentials from `existingSecret` are injected at runtime and are unaffected.)
381+
</Note>
382+
294383
**Using existing secrets (recommended):**
295384

296385
```yaml
297386
clickhouse:
298387
deploy: false
299388
external:
300389
host: "my-clickhouse.example.com"
301-
port: 8123
390+
httpPort: 8123
302391
username: "my-username"
303392
existingSecret: "clickhouse-credentials"
304393
# existingSecretKey: "clickhouse-password" # default (optional)

hosting/docker/.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ OBJECT_STORE_SECRET_ACCESS_KEY=
136136
# POSTGRES_IMAGE_TAG=14
137137
# REDIS_IMAGE_TAG=7
138138
# ELECTRIC_IMAGE_TAG=1.0.13
139-
# CLICKHOUSE_IMAGE_TAG=latest
139+
# CLICKHOUSE_IMAGE_TAG=26.2
140140
# REGISTRY_IMAGE_TAG=2
141141
# MINIO_IMAGE_TAG=latest
142142
# DOCKER_PROXY_IMAGE_TAG=latest
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<!--
2+
Keeps ClickHouse's on-disk layout compatible with data volumes created by
3+
the previous Bitnami-based setup, which stored everything under a data/
4+
subdirectory of the volume. Fresh installs get the same layout. tmp lives
5+
outside data/ because old volumes contain a dangling tmp symlink there.
6+
-->
7+
<clickhouse>
8+
<path>/var/lib/clickhouse/data/</path>
9+
<tmp_path>/var/lib/clickhouse/tmp/</tmp_path>
10+
<user_files_path>/var/lib/clickhouse/data/user_files/</user_files_path>
11+
<format_schema_path>/var/lib/clickhouse/data/format_schemas/</format_schema_path>
12+
<user_directories>
13+
<local_directory>
14+
<path>/var/lib/clickhouse/data/access/</path>
15+
</local_directory>
16+
</user_directories>
17+
</clickhouse>

hosting/docker/webapp/docker-compose.yml

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,11 @@ services:
8080
TRIGGER_BOOTSTRAP_WORKER_GROUP_NAME: bootstrap
8181
TRIGGER_BOOTSTRAP_WORKER_TOKEN_PATH: /home/node/shared/worker_token
8282
# ClickHouse configuration
83-
CLICKHOUSE_URL: ${CLICKHOUSE_URL:-http://default:${CLICKHOUSE_PASSWORD}@clickhouse:8123?secure=false}
83+
CLICKHOUSE_URL: ${CLICKHOUSE_URL:-http://${CLICKHOUSE_USER:-default}:${CLICKHOUSE_PASSWORD}@clickhouse:8123?secure=false}
8484
CLICKHOUSE_LOG_LEVEL: ${CLICKHOUSE_LOG_LEVEL:-info}
8585
# Run replication
8686
RUN_REPLICATION_ENABLED: ${RUN_REPLICATION_ENABLED:-1}
87-
RUN_REPLICATION_CLICKHOUSE_URL: ${RUN_REPLICATION_CLICKHOUSE_URL:-http://default:${CLICKHOUSE_PASSWORD}@clickhouse:8123}
87+
RUN_REPLICATION_CLICKHOUSE_URL: ${RUN_REPLICATION_CLICKHOUSE_URL:-http://${CLICKHOUSE_USER:-default}:${CLICKHOUSE_PASSWORD}@clickhouse:8123}
8888
RUN_REPLICATION_LOG_LEVEL: ${RUN_REPLICATION_LOG_LEVEL:-info}
8989
# Limits
9090
# TASK_PAYLOAD_OFFLOAD_THRESHOLD: 524288 # 512KB
@@ -157,18 +157,26 @@ services:
157157
start_period: 10s
158158

159159
clickhouse:
160-
image: bitnamilegacy/clickhouse:${CLICKHOUSE_IMAGE_TAG:-latest}
160+
image: clickhouse/clickhouse-server:${CLICKHOUSE_IMAGE_TAG:-26.2}
161161
restart: ${RESTART_POLICY:-unless-stopped}
162162
logging: *logging-config
163163
ports:
164164
- ${CLICKHOUSE_PUBLISH_IP:-127.0.0.1}:9123:8123
165165
- ${CLICKHOUSE_PUBLISH_IP:-127.0.0.1}:9090:9000
166+
ulimits:
167+
nofile:
168+
soft: 262144
169+
hard: 262144
166170
environment:
167-
CLICKHOUSE_ADMIN_USER: ${CLICKHOUSE_USER:-default}
168-
CLICKHOUSE_ADMIN_PASSWORD: ${CLICKHOUSE_PASSWORD:?Set CLICKHOUSE_PASSWORD in .env - run ./generate-secrets.sh}
171+
CLICKHOUSE_USER: ${CLICKHOUSE_USER:-default}
172+
CLICKHOUSE_PASSWORD: ${CLICKHOUSE_PASSWORD:?Set CLICKHOUSE_PASSWORD in .env - run ./generate-secrets.sh}
173+
CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT: 1
169174
volumes:
170-
- clickhouse:/bitnami/clickhouse
171-
- ../clickhouse/override.xml:/bitnami/clickhouse/etc/config.d/override.xml:ro
175+
# The same volume works across upgrades from the previous Bitnami-based
176+
# setup: data-paths.xml keeps the on-disk layout compatible.
177+
- clickhouse:/var/lib/clickhouse
178+
- ../clickhouse/data-paths.xml:/etc/clickhouse-server/config.d/data-paths.xml:ro
179+
- ../clickhouse/override.xml:/etc/clickhouse-server/config.d/override.xml:ro
172180
networks:
173181
- webapp
174182
healthcheck:

hosting/k8s/helm/Chart.lock

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,8 @@ dependencies:
55
- name: redis
66
repository: oci://registry-1.docker.io/bitnamicharts
77
version: 21.2.6
8-
- name: clickhouse
9-
repository: oci://registry-1.docker.io/bitnamicharts
10-
version: 9.4.4
118
- name: minio
129
repository: oci://registry-1.docker.io/bitnamicharts
1310
version: 17.0.9
14-
digest: sha256:e1b572ab8eca0cc376311398c27b1734d8a598095fccc81dd9c32b2c8b9c1149
15-
generated: "2026-05-05T10:31:58.493590751+01:00"
11+
digest: sha256:a735954c8b78fcf5b30689bdcdfed66b9be57135368ea696aff2b52ecd731474
12+
generated: "2026-07-13T16:36:15.800113+01:00"

hosting/k8s/helm/Chart.yaml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,6 @@ dependencies:
2626
version: "21.2.6"
2727
repository: "oci://registry-1.docker.io/bitnamicharts"
2828
condition: redis.deploy
29-
- name: clickhouse
30-
version: "9.4.4"
31-
repository: "oci://registry-1.docker.io/bitnamicharts"
32-
condition: clickhouse.deploy
3329
- name: minio
3430
version: "17.0.9"
3531
repository: "oci://registry-1.docker.io/bitnamicharts"

hosting/k8s/helm/templates/_helpers.tpl

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -408,45 +408,81 @@ http://{{ include "trigger-v4.fullname" . }}-s2:{{ .Values.s2.service.port }}/v1
408408
{{- end -}}
409409
{{- end }}
410410

411+
{{/*
412+
Percent-encode a string for the userinfo part of a URL. urlquery encodes
413+
spaces as `+` (query semantics), which userinfo decoding keeps literal; a
414+
real `+` becomes `%2B`, so any `+` left in the output is a space and can be
415+
rewritten to `%20`.
416+
*/}}
417+
{{- define "trigger-v4.urlencode" -}}
418+
{{- . | urlquery | replace "+" "%20" -}}
419+
{{- end }}
420+
421+
{{/*
422+
ClickHouse data-paths config. Keeps the on-disk layout compatible with data
423+
volumes created by the Bitnami subchart this chart used previously, which
424+
stored everything under a data/ subdirectory of the volume. Fresh installs
425+
get the same layout. tmp lives outside data/ because old volumes contain a
426+
dangling tmp symlink there. Users can override by defining their own
427+
data-paths.xml in clickhouse.configdFiles.
428+
*/}}
429+
{{- define "trigger-v4.clickhouse.dataPathsConfig" -}}
430+
<clickhouse>
431+
<path>/var/lib/clickhouse/data/</path>
432+
<tmp_path>/var/lib/clickhouse/tmp/</tmp_path>
433+
<user_files_path>/var/lib/clickhouse/data/user_files/</user_files_path>
434+
<format_schema_path>/var/lib/clickhouse/data/format_schemas/</format_schema_path>
435+
<user_directories>
436+
<local_directory>
437+
<path>/var/lib/clickhouse/data/access/</path>
438+
</local_directory>
439+
</user_directories>
440+
</clickhouse>
441+
{{- end }}
442+
411443
{{/*
412444
ClickHouse hostname
413445
*/}}
414446
{{- define "trigger-v4.clickhouse.hostname" -}}
415447
{{- if .Values.clickhouse.host }}
416448
{{- .Values.clickhouse.host }}
417449
{{- else if .Values.clickhouse.deploy }}
418-
{{- printf "%s-clickhouse" .Release.Name }}
450+
{{- printf "%s-clickhouse" (include "trigger-v4.fullname" .) }}
419451
{{- end }}
420452
{{- end }}
421453

422454
{{/*
423455
ClickHouse URL for application (with secure parameter)
424456
425-
Note on the external+existingSecret branch: the password is expanded via
426-
Kubernetes' `$(VAR)` syntax, not shell `${VAR}`. Kubelet substitutes
427-
`$(CLICKHOUSE_PASSWORD)` at container-creation time from the
457+
Note on the deploy and external+existingSecret branches: the password is
458+
expanded via Kubernetes' `$(VAR)` syntax, not shell `${VAR}`. Kubelet
459+
substitutes `$(CLICKHOUSE_PASSWORD)` at container-creation time from the
428460
CLICKHOUSE_PASSWORD env var declared just before CLICKHOUSE_URL in
429461
webapp.yaml. Shell-style `${...}` does not work here because
430462
`docker/scripts/entrypoint.sh` assigns CLICKHOUSE_URL to GOOSE_DBSTRING
431463
with a single-pass expansion (`export GOOSE_DBSTRING="$CLICKHOUSE_URL"`),
432464
so any inner `${...}` reaches goose verbatim and fails URL parsing.
433465
434466
CLICKHOUSE_PASSWORD must contain only URL-userinfo-safe characters — the
435-
value is substituted verbatim, so `@ : / ? # [ ] %` break the URL. Use a
436-
hex-encoded password or percent-encode before storing in the Secret.
467+
value is substituted verbatim, so `@ : / ? # [ ] %` break the URL. The
468+
chart-generated datastore password is hex, which is safe; a pinned
469+
auth.password or external Secret value must be URL-safe too.
470+
471+
Inline credentials (usernames and the external plain password) are
472+
percent-encoded, so any special characters are safe there.
437473
*/}}
438474
{{- define "trigger-v4.clickhouse.url" -}}
439475
{{- if .Values.clickhouse.deploy -}}
440476
{{- $protocol := ternary "https" "http" .Values.clickhouse.secure -}}
441477
{{- $secure := ternary "true" "false" .Values.clickhouse.secure -}}
442-
{{ $protocol }}://{{ .Values.clickhouse.auth.username }}:$(CLICKHOUSE_PASSWORD)@{{ include "trigger-v4.clickhouse.hostname" . }}:8123?secure={{ $secure }}
478+
{{ $protocol }}://{{ include "trigger-v4.urlencode" .Values.clickhouse.auth.username }}:$(CLICKHOUSE_PASSWORD)@{{ include "trigger-v4.clickhouse.hostname" . }}:{{ .Values.clickhouse.service.ports.http }}?secure={{ $secure }}
443479
{{- else if .Values.clickhouse.external.host -}}
444480
{{- $protocol := ternary "https" "http" .Values.clickhouse.external.secure -}}
445481
{{- $secure := ternary "true" "false" .Values.clickhouse.external.secure -}}
446482
{{- if .Values.clickhouse.external.existingSecret -}}
447-
{{ $protocol }}://{{ .Values.clickhouse.external.username }}:$(CLICKHOUSE_PASSWORD)@{{ .Values.clickhouse.external.host }}:{{ .Values.clickhouse.external.httpPort | default 8123 }}?secure={{ $secure }}
483+
{{ $protocol }}://{{ include "trigger-v4.urlencode" .Values.clickhouse.external.username }}:$(CLICKHOUSE_PASSWORD)@{{ .Values.clickhouse.external.host }}:{{ .Values.clickhouse.external.httpPort | default 8123 }}?secure={{ $secure }}
448484
{{- else -}}
449-
{{ $protocol }}://{{ .Values.clickhouse.external.username }}:{{ .Values.clickhouse.external.password }}@{{ .Values.clickhouse.external.host }}:{{ .Values.clickhouse.external.httpPort | default 8123 }}?secure={{ $secure }}
485+
{{ $protocol }}://{{ include "trigger-v4.urlencode" .Values.clickhouse.external.username }}:{{ include "trigger-v4.urlencode" .Values.clickhouse.external.password }}@{{ .Values.clickhouse.external.host }}:{{ .Values.clickhouse.external.httpPort | default 8123 }}?secure={{ $secure }}
450486
{{- end -}}
451487
{{- end -}}
452488
{{- end }}
@@ -460,13 +496,13 @@ applies to the replication URL.
460496
{{- define "trigger-v4.clickhouse.replication.url" -}}
461497
{{- if .Values.clickhouse.deploy -}}
462498
{{- $protocol := ternary "https" "http" .Values.clickhouse.secure -}}
463-
{{ $protocol }}://{{ .Values.clickhouse.auth.username }}:$(CLICKHOUSE_PASSWORD)@{{ include "trigger-v4.clickhouse.hostname" . }}:8123
499+
{{ $protocol }}://{{ include "trigger-v4.urlencode" .Values.clickhouse.auth.username }}:$(CLICKHOUSE_PASSWORD)@{{ include "trigger-v4.clickhouse.hostname" . }}:{{ .Values.clickhouse.service.ports.http }}
464500
{{- else if .Values.clickhouse.external.host -}}
465501
{{- $protocol := ternary "https" "http" .Values.clickhouse.external.secure -}}
466502
{{- if .Values.clickhouse.external.existingSecret -}}
467-
{{ $protocol }}://{{ .Values.clickhouse.external.username }}:$(CLICKHOUSE_PASSWORD)@{{ .Values.clickhouse.external.host }}:{{ .Values.clickhouse.external.httpPort | default 8123 }}
503+
{{ $protocol }}://{{ include "trigger-v4.urlencode" .Values.clickhouse.external.username }}:$(CLICKHOUSE_PASSWORD)@{{ .Values.clickhouse.external.host }}:{{ .Values.clickhouse.external.httpPort | default 8123 }}
468504
{{- else -}}
469-
{{ $protocol }}://{{ .Values.clickhouse.external.username }}:{{ .Values.clickhouse.external.password }}@{{ .Values.clickhouse.external.host }}:{{ .Values.clickhouse.external.httpPort | default 8123 }}
505+
{{ $protocol }}://{{ include "trigger-v4.urlencode" .Values.clickhouse.external.username }}:{{ include "trigger-v4.urlencode" .Values.clickhouse.external.password }}@{{ .Values.clickhouse.external.host }}:{{ .Values.clickhouse.external.httpPort | default 8123 }}
470506
{{- end -}}
471507
{{- end -}}
472508
{{- end }}

0 commit comments

Comments
 (0)