Skip to content

Commit 94c7fb2

Browse files
committed
fix(hosting): deploy ClickHouse from the official image instead of Bitnami
The Bitnami free image catalog is EOL and its frozen bitnamilegacy archive tops out at ClickHouse 25.7.5, below the 25.8 floor the platform requires since v4.5.0. The Docker Compose stack and the Helm chart now run the official clickhouse/clickhouse-server image at 26.2, the same version the platform is developed and tested against. The Helm chart deploys ClickHouse with a chart-owned StatefulSet instead of the Bitnami subchart. Existing deployments keep their data with no manual steps: a config override keeps the on-disk layout compatible with volumes created by the Bitnami-based setup, Compose reuses the same named volume, and the Helm chart automatically adopts the data PVC left behind by the old subchart.
1 parent 109e245 commit 94c7fb2

12 files changed

Lines changed: 313 additions & 36 deletions

File tree

docs/self-hosting/docker.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,8 @@ 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+
365367
<Note>
366368
Trigger.dev 4.5.0 is the last version we officially support for running v3 (SDK v3) tasks. If
367369
you still have v3 tasks, pin `TRIGGER_IMAGE_TAG` to exactly `v4.5.0` or [migrate to

docs/self-hosting/kubernetes.mdx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,14 +279,24 @@ redis:
279279
280280
#### ClickHouse
281281
282+
<Note>Trigger.dev requires ClickHouse 25.8 or newer.</Note>
283+
284+
<Note>
285+
When upgrading from a chart version that bundled ClickHouse via the Bitnami subchart, the chart
286+
automatically adopts the existing data volume, so no manual migration is needed. If you render
287+
manifests without cluster access (for example with GitOps tools that use `helm template`), set
288+
`clickhouse.persistence.existingClaim` to the old PVC name
289+
(`data-<release>-clickhouse-shard0-0`) to keep your data.
290+
</Note>
291+
282292
**Direct configuration:**
283293

284294
```yaml
285295
clickhouse:
286296
deploy: false
287297
external:
288298
host: "my-clickhouse.example.com"
289-
port: 8123
299+
httpPort: 8123
290300
username: "my-username"
291301
password: "my-password"
292302
```
@@ -298,7 +308,7 @@ clickhouse:
298308
deploy: false
299309
external:
300310
host: "my-clickhouse.example.com"
301-
port: 8123
311+
httpPort: 8123
302312
username: "my-username"
303313
existingSecret: "clickhouse-credentials"
304314
# 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: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ ClickHouse hostname
415415
{{- if .Values.clickhouse.host }}
416416
{{- .Values.clickhouse.host }}
417417
{{- else if .Values.clickhouse.deploy }}
418-
{{- printf "%s-clickhouse" .Release.Name }}
418+
{{- printf "%s-clickhouse" (include "trigger-v4.fullname" .) }}
419419
{{- end }}
420420
{{- end }}
421421

@@ -439,7 +439,7 @@ hex-encoded password or percent-encode before storing in the Secret.
439439
{{- if .Values.clickhouse.deploy -}}
440440
{{- $protocol := ternary "https" "http" .Values.clickhouse.secure -}}
441441
{{- $secure := ternary "true" "false" .Values.clickhouse.secure -}}
442-
{{ $protocol }}://{{ .Values.clickhouse.auth.username }}:$(CLICKHOUSE_PASSWORD)@{{ include "trigger-v4.clickhouse.hostname" . }}:8123?secure={{ $secure }}
442+
{{ $protocol }}://{{ .Values.clickhouse.auth.username }}:$(CLICKHOUSE_PASSWORD)@{{ include "trigger-v4.clickhouse.hostname" . }}:{{ .Values.clickhouse.service.ports.http }}?secure={{ $secure }}
443443
{{- else if .Values.clickhouse.external.host -}}
444444
{{- $protocol := ternary "https" "http" .Values.clickhouse.external.secure -}}
445445
{{- $secure := ternary "true" "false" .Values.clickhouse.external.secure -}}
@@ -460,7 +460,7 @@ applies to the replication URL.
460460
{{- define "trigger-v4.clickhouse.replication.url" -}}
461461
{{- if .Values.clickhouse.deploy -}}
462462
{{- $protocol := ternary "https" "http" .Values.clickhouse.secure -}}
463-
{{ $protocol }}://{{ .Values.clickhouse.auth.username }}:$(CLICKHOUSE_PASSWORD)@{{ include "trigger-v4.clickhouse.hostname" . }}:8123
463+
{{ $protocol }}://{{ .Values.clickhouse.auth.username }}:$(CLICKHOUSE_PASSWORD)@{{ include "trigger-v4.clickhouse.hostname" . }}:{{ .Values.clickhouse.service.ports.http }}
464464
{{- else if .Values.clickhouse.external.host -}}
465465
{{- $protocol := ternary "https" "http" .Values.clickhouse.external.secure -}}
466466
{{- if .Values.clickhouse.external.existingSecret -}}
Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
{{- if .Values.clickhouse.deploy }}
2+
apiVersion: v1
3+
kind: ConfigMap
4+
metadata:
5+
name: {{ include "trigger-v4.fullname" . }}-clickhouse-config
6+
labels:
7+
{{- $component := "clickhouse" }}
8+
{{- include "trigger-v4.componentLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 4 }}
9+
data:
10+
{{- if not (hasKey .Values.clickhouse.configdFiles "data-paths.xml") }}
11+
{{- /* Keeps the on-disk layout compatible with data volumes created by the
12+
Bitnami subchart this chart used previously, which stored everything
13+
under a data/ subdirectory of the volume. Fresh installs get the same
14+
layout. tmp lives outside data/ because old volumes contain a
15+
dangling tmp symlink there. */}}
16+
data-paths.xml: |
17+
<clickhouse>
18+
<path>/var/lib/clickhouse/data/</path>
19+
<tmp_path>/var/lib/clickhouse/tmp/</tmp_path>
20+
<user_files_path>/var/lib/clickhouse/data/user_files/</user_files_path>
21+
<format_schema_path>/var/lib/clickhouse/data/format_schemas/</format_schema_path>
22+
<user_directories>
23+
<local_directory>
24+
<path>/var/lib/clickhouse/data/access/</path>
25+
</local_directory>
26+
</user_directories>
27+
</clickhouse>
28+
{{- end }}
29+
{{- range $filename, $content := .Values.clickhouse.configdFiles }}
30+
{{ $filename }}: |
31+
{{- $content | nindent 4 }}
32+
{{- end }}
33+
---
34+
{{- /* Reuse an existing data PVC instead of creating one via
35+
volumeClaimTemplates. Set explicitly through persistence.existingClaim,
36+
or detected automatically: upgrades from chart versions that bundled
37+
the Bitnami subchart leave their PVC behind under the old name, and
38+
adopting it preserves all ClickHouse data with no manual migration.
39+
(lookup returns nothing during template/dry-run rendering; set
40+
persistence.existingClaim explicitly when pre-rendering manifests,
41+
e.g. with GitOps tools.) */}}
42+
{{- $existingClaim := .Values.clickhouse.persistence.existingClaim }}
43+
{{- if and (not $existingClaim) .Values.clickhouse.persistence.enabled }}
44+
{{- $legacyName := printf "data-%s-clickhouse-shard0-0" .Release.Name }}
45+
{{- if lookup "v1" "PersistentVolumeClaim" .Release.Namespace $legacyName }}
46+
{{- $existingClaim = $legacyName }}
47+
{{- end }}
48+
{{- end }}
49+
apiVersion: apps/v1
50+
kind: StatefulSet
51+
metadata:
52+
name: {{ include "trigger-v4.fullname" . }}-clickhouse
53+
labels:
54+
{{- $component := "clickhouse" }}
55+
{{- include "trigger-v4.componentLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 4 }}
56+
spec:
57+
replicas: 1
58+
serviceName: {{ include "trigger-v4.fullname" . }}-clickhouse
59+
selector:
60+
matchLabels:
61+
{{- include "trigger-v4.componentSelectorLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 6 }}
62+
template:
63+
metadata:
64+
annotations:
65+
checksum/config: {{ .Values.clickhouse.configdFiles | toYaml | sha256sum }}
66+
{{- with .Values.clickhouse.podAnnotations }}
67+
{{- toYaml . | nindent 8 }}
68+
{{- end }}
69+
labels:
70+
{{- include "trigger-v4.componentSelectorLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 8 }}
71+
spec:
72+
{{- with .Values.global.imagePullSecrets }}
73+
imagePullSecrets:
74+
{{- toYaml . | nindent 8 }}
75+
{{- end }}
76+
{{- with .Values.clickhouse.podSecurityContext }}
77+
securityContext:
78+
{{- toYaml . | nindent 8 }}
79+
{{- end }}
80+
containers:
81+
- name: clickhouse
82+
{{- with .Values.clickhouse.securityContext }}
83+
securityContext:
84+
{{- toYaml . | nindent 12 }}
85+
{{- end }}
86+
image: "{{ .Values.global.imageRegistry | default .Values.clickhouse.image.registry }}/{{ .Values.clickhouse.image.repository }}:{{ .Values.clickhouse.image.tag }}{{ with .Values.clickhouse.image.digest }}@{{ . }}{{ end }}"
87+
imagePullPolicy: {{ .Values.clickhouse.image.pullPolicy }}
88+
env:
89+
- name: CLICKHOUSE_USER
90+
value: {{ .Values.clickhouse.auth.username | quote }}
91+
{{- /* Same chart-managed datastore secret the webapp reads for its
92+
connection URL, so the server credential and the app's URL
93+
always match. */}}
94+
- name: CLICKHOUSE_PASSWORD
95+
valueFrom:
96+
secretKeyRef:
97+
name: {{ .Values.clickhouse.auth.existingSecret | default (include "trigger-v4.datastore.secretName" .) }}
98+
key: {{ .Values.clickhouse.auth.existingSecretKey | default "clickhouse-admin-password" }}
99+
- name: CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT
100+
value: "1"
101+
ports:
102+
- name: http
103+
containerPort: 8123
104+
protocol: TCP
105+
- name: native
106+
containerPort: 9000
107+
protocol: TCP
108+
{{- if .Values.clickhouse.livenessProbe.enabled }}
109+
livenessProbe:
110+
httpGet:
111+
path: /ping
112+
port: http
113+
initialDelaySeconds: {{ .Values.clickhouse.livenessProbe.initialDelaySeconds }}
114+
periodSeconds: {{ .Values.clickhouse.livenessProbe.periodSeconds }}
115+
timeoutSeconds: {{ .Values.clickhouse.livenessProbe.timeoutSeconds }}
116+
failureThreshold: {{ .Values.clickhouse.livenessProbe.failureThreshold }}
117+
successThreshold: {{ .Values.clickhouse.livenessProbe.successThreshold }}
118+
{{- end }}
119+
{{- if .Values.clickhouse.readinessProbe.enabled }}
120+
readinessProbe:
121+
httpGet:
122+
path: /ping
123+
port: http
124+
initialDelaySeconds: {{ .Values.clickhouse.readinessProbe.initialDelaySeconds }}
125+
periodSeconds: {{ .Values.clickhouse.readinessProbe.periodSeconds }}
126+
timeoutSeconds: {{ .Values.clickhouse.readinessProbe.timeoutSeconds }}
127+
failureThreshold: {{ .Values.clickhouse.readinessProbe.failureThreshold }}
128+
successThreshold: {{ .Values.clickhouse.readinessProbe.successThreshold }}
129+
{{- end }}
130+
resources:
131+
{{- toYaml .Values.clickhouse.resources | nindent 12 }}
132+
volumeMounts:
133+
- name: data
134+
mountPath: /var/lib/clickhouse
135+
- name: logs
136+
mountPath: /var/log/clickhouse-server
137+
{{- /* Mount each override file individually: shadowing the whole
138+
config.d directory would remove the image's built-in
139+
docker_related_config.xml, which makes the server listen on
140+
0.0.0.0 instead of localhost only. */}}
141+
{{- if not (hasKey .Values.clickhouse.configdFiles "data-paths.xml") }}
142+
- name: config
143+
mountPath: /etc/clickhouse-server/config.d/data-paths.xml
144+
subPath: data-paths.xml
145+
{{- end }}
146+
{{- range $filename, $_ := .Values.clickhouse.configdFiles }}
147+
- name: config
148+
mountPath: /etc/clickhouse-server/config.d/{{ $filename }}
149+
subPath: {{ $filename }}
150+
{{- end }}
151+
volumes:
152+
- name: config
153+
configMap:
154+
name: {{ include "trigger-v4.fullname" . }}-clickhouse-config
155+
- name: logs
156+
emptyDir: {}
157+
{{- if not .Values.clickhouse.persistence.enabled }}
158+
- name: data
159+
emptyDir: {}
160+
{{- else if $existingClaim }}
161+
- name: data
162+
persistentVolumeClaim:
163+
claimName: {{ $existingClaim }}
164+
{{- end }}
165+
{{- if and .Values.clickhouse.persistence.enabled (not $existingClaim) }}
166+
volumeClaimTemplates:
167+
- metadata:
168+
name: data
169+
{{- if .Values.clickhouse.persistence.retain }}
170+
annotations:
171+
helm.sh/resource-policy: keep
172+
{{- end }}
173+
spec:
174+
accessModes:
175+
- {{ .Values.clickhouse.persistence.accessMode }}
176+
resources:
177+
requests:
178+
storage: {{ .Values.clickhouse.persistence.size }}
179+
{{- $storageClass := .Values.clickhouse.persistence.storageClass | default .Values.global.storageClass }}
180+
{{- if $storageClass }}
181+
storageClassName: {{ $storageClass }}
182+
{{- end }}
183+
{{- end }}
184+
---
185+
apiVersion: v1
186+
kind: Service
187+
metadata:
188+
name: {{ include "trigger-v4.fullname" . }}-clickhouse
189+
labels:
190+
{{- $component := "clickhouse" }}
191+
{{- include "trigger-v4.componentLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 4 }}
192+
spec:
193+
type: {{ .Values.clickhouse.service.type }}
194+
ports:
195+
- port: {{ .Values.clickhouse.service.ports.http }}
196+
targetPort: http
197+
protocol: TCP
198+
name: http
199+
- port: {{ .Values.clickhouse.service.ports.native }}
200+
targetPort: native
201+
protocol: TCP
202+
name: native
203+
selector:
204+
{{- include "trigger-v4.componentSelectorLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 4 }}
205+
{{- end }}

hosting/k8s/helm/templates/tests/test-clickhouse.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@ spec:
1616
args:
1717
- |
1818
echo "Testing ClickHouse HTTP interface..."
19-
curl -f --user "{{ .Values.clickhouse.auth.adminUser }}:{{ .Values.clickhouse.auth.adminPassword }}" "http://{{ include "trigger-v4.fullname" . }}-clickhouse:{{ .Values.clickhouse.service.ports.http }}/ping"
19+
curl -f --user "{{ .Values.clickhouse.auth.username }}:{{ .Values.clickhouse.auth.password }}" "http://{{ include "trigger-v4.clickhouse.hostname" . }}:{{ .Values.clickhouse.service.ports.http }}/ping"
2020
echo "ClickHouse test completed successfully"
2121
{{- end }}

0 commit comments

Comments
 (0)