@trigger.dev/sdk 4.5.8 → 4.5.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/dist/commonjs/package.json +2 -1
  2. package/dist/commonjs/v3/agentSkillsRuntime.js.map +1 -1
  3. package/dist/commonjs/v3/ai-shared.js.map +1 -1
  4. package/dist/commonjs/v3/ai.js +15 -1
  5. package/dist/commonjs/v3/ai.js.map +1 -1
  6. package/dist/commonjs/v3/aiAutoTelemetry.js.map +1 -1
  7. package/dist/commonjs/v3/auth.js.map +1 -1
  8. package/dist/commonjs/v3/batchDebounce.test.d.ts +1 -0
  9. package/dist/commonjs/v3/batchDebounce.test.js +189 -0
  10. package/dist/commonjs/v3/batchDebounce.test.js.map +1 -0
  11. package/dist/commonjs/v3/cache.js.map +1 -1
  12. package/dist/commonjs/v3/chat-client.d.ts +14 -1
  13. package/dist/commonjs/v3/chat-client.js +19 -2
  14. package/dist/commonjs/v3/chat-client.js.map +1 -1
  15. package/dist/commonjs/v3/chat-react.js +1 -1
  16. package/dist/commonjs/v3/chat-react.js.map +1 -1
  17. package/dist/commonjs/v3/chat-tab-coordinator.js.map +1 -1
  18. package/dist/commonjs/v3/chat-tab-coordinator.test.js.map +1 -1
  19. package/dist/commonjs/v3/chat.js +2 -2
  20. package/dist/commonjs/v3/chat.js.map +1 -1
  21. package/dist/commonjs/v3/chat.test.js.map +1 -1
  22. package/dist/commonjs/v3/config.js.map +1 -1
  23. package/dist/commonjs/v3/envvars.js.map +1 -1
  24. package/dist/commonjs/v3/hooks.js.map +1 -1
  25. package/dist/commonjs/v3/index.js.map +1 -1
  26. package/dist/commonjs/v3/locals.js.map +1 -1
  27. package/dist/commonjs/v3/metadata.js.map +1 -1
  28. package/dist/commonjs/v3/prompt.js.map +1 -1
  29. package/dist/commonjs/v3/promptManagement.js.map +1 -1
  30. package/dist/commonjs/v3/queues.js.map +1 -1
  31. package/dist/commonjs/v3/retry.js.map +1 -1
  32. package/dist/commonjs/v3/runs.d.ts +81 -81
  33. package/dist/commonjs/v3/runs.js.map +1 -1
  34. package/dist/commonjs/v3/schedules/index.js.map +1 -1
  35. package/dist/commonjs/v3/sessions.js.map +1 -1
  36. package/dist/commonjs/v3/shared.d.ts +2 -1
  37. package/dist/commonjs/v3/shared.js +7 -0
  38. package/dist/commonjs/v3/shared.js.map +1 -1
  39. package/dist/commonjs/v3/shared.test.js +9 -0
  40. package/dist/commonjs/v3/shared.test.js.map +1 -1
  41. package/dist/commonjs/v3/skill.js.map +1 -1
  42. package/dist/commonjs/v3/streams.js.map +1 -1
  43. package/dist/commonjs/v3/tasks.js.map +1 -1
  44. package/dist/commonjs/v3/test/mock-chat-agent.js.map +1 -1
  45. package/dist/commonjs/v3/test/test-session-handle.js.map +1 -1
  46. package/dist/commonjs/v3/triggerClient.js.map +1 -1
  47. package/dist/commonjs/v3/triggerClient.types.test.js.map +1 -1
  48. package/dist/commonjs/v3/wait.d.ts +6 -1
  49. package/dist/commonjs/v3/waitUntil.js.map +1 -1
  50. package/dist/commonjs/v3/webhooks.js.map +1 -1
  51. package/dist/commonjs/version.js +1 -1
  52. package/dist/esm/package.json +2 -1
  53. package/dist/esm/v3/ai.js +15 -1
  54. package/dist/esm/v3/ai.js.map +1 -1
  55. package/dist/esm/v3/auth.js.map +1 -1
  56. package/dist/esm/v3/batchDebounce.test.d.ts +1 -0
  57. package/dist/esm/v3/batchDebounce.test.js +187 -0
  58. package/dist/esm/v3/batchDebounce.test.js.map +1 -0
  59. package/dist/esm/v3/chat-client.d.ts +14 -1
  60. package/dist/esm/v3/chat-client.js +19 -2
  61. package/dist/esm/v3/chat-client.js.map +1 -1
  62. package/dist/esm/v3/chat-tab-coordinator.js.map +1 -1
  63. package/dist/esm/v3/chat-tab-coordinator.test.js.map +1 -1
  64. package/dist/esm/v3/chat.js +2 -2
  65. package/dist/esm/v3/chat.js.map +1 -1
  66. package/dist/esm/v3/chat.test.js.map +1 -1
  67. package/dist/esm/v3/metadata.js.map +1 -1
  68. package/dist/esm/v3/retry.js.map +1 -1
  69. package/dist/esm/v3/runs.d.ts +80 -80
  70. package/dist/esm/v3/sessions.js.map +1 -1
  71. package/dist/esm/v3/shared.d.ts +2 -1
  72. package/dist/esm/v3/shared.js +6 -0
  73. package/dist/esm/v3/shared.js.map +1 -1
  74. package/dist/esm/v3/shared.test.js +10 -1
  75. package/dist/esm/v3/shared.test.js.map +1 -1
  76. package/dist/esm/v3/test/mock-chat-agent.js.map +1 -1
  77. package/dist/esm/v3/test/test-session-handle.js.map +1 -1
  78. package/dist/esm/v3/triggerClient.js.map +1 -1
  79. package/dist/esm/v3/wait.d.ts +6 -1
  80. package/dist/esm/version.js +1 -1
  81. package/docs/ai-chat/changelog.mdx +1 -1
  82. package/docs/ai-chat/client-protocol.mdx +4 -2
  83. package/docs/ai-chat/fast-starts.mdx +4 -1
  84. package/docs/ai-chat/how-it-works.mdx +1 -1
  85. package/docs/ai-chat/migrating-from-a-route-handler.mdx +592 -0
  86. package/docs/bulk-actions.mdx +2 -1
  87. package/docs/config/extensions/emitDecoratorMetadata.mdx +27 -4
  88. package/docs/config/extensions/lightpanda.mdx +1 -1
  89. package/docs/config/extensions/puppeteer.mdx +1 -1
  90. package/docs/how-it-works.mdx +4 -4
  91. package/docs/how-to-reduce-your-spend.mdx +4 -4
  92. package/docs/mcp-tools.mdx +1 -1
  93. package/docs/queue-concurrency.mdx +4 -0
  94. package/docs/runs/bulk-actions.mdx +2 -1
  95. package/docs/self-hosting/docker.mdx +9 -0
  96. package/docs/self-hosting/env/supervisor.mdx +2 -1
  97. package/docs/self-hosting/env/webapp.mdx +5 -1
  98. package/docs/self-hosting/kubernetes.mdx +281 -221
  99. package/docs/triggering.mdx +16 -4
  100. package/package.json +4 -3
@@ -1,15 +1,41 @@
1
1
  ---
2
2
  title: "Kubernetes"
3
- description: "You can self-host Trigger.dev in Kubernetes using our official Helm chart."
3
+ description: "Deploy Trigger.dev to Kubernetes with our official Helm chart - one command for evaluation, external datastores for production."
4
4
  ---
5
5
 
6
- The following instructions will help you deploy Trigger.dev to Kubernetes using our official Helm chart. Make sure to read the self-hosting [overview](/self-hosting/overview) first.
6
+ The official Helm chart installs the full Trigger.dev stack into a Kubernetes namespace. Read the self-hosting [overview](/self-hosting/overview) first.
7
7
 
8
- As self-hosted deployments tend to have unique requirements and configurations, we don't provide specific advice for securing your deployment, scaling up, or improving reliability.
8
+ Pick a path and stay on it. Run the **evaluation install** to try Trigger.dev with everything bundled in-cluster - one `helm install`, default values, no external dependencies. Run the **production install** for real workloads: external Postgres, Redis, ClickHouse, and object storage, your own secrets, and HA on the datastores you already operate. Each configuration decision below belongs to one path or the other.
9
9
 
10
- Should the burden ever get too much, we'd be happy to see you on [Trigger.dev cloud](https://trigger.dev/pricing) where we deal with these concerns for you.
10
+ This guide alone is unlikely to produce a hardened production deployment - securing, scaling, and reliability-tuning your cluster remain yours to own. Should the burden get too much, we'd be happy to see you on [Trigger.dev cloud](https://trigger.dev/pricing) where we deal with these concerns for you.
11
11
 
12
- **Warning:** This guide alone is unlikely to result in a production-ready deployment. Security, scaling, and reliability concerns are not fully addressed here.
12
+ ## Architecture
13
+
14
+ The chart deploys a webapp, a supervisor, and the datastores they depend on. The supervisor pulls runs from the webapp and schedules each one onto a worker node, which executes the task in a container sized by its machine preset.
15
+
16
+ ```mermaid
17
+ flowchart TD
18
+ webapp["webapp<br/>API + dashboard"]
19
+ supervisor["supervisor"]
20
+ workers["worker nodes<br/>task containers"]
21
+ pg[("Postgres<br/>primary DB")]
22
+ redis[("Redis<br/>queue / state")]
23
+ ch[("ClickHouse<br/>task events v2")]
24
+ obj[("object storage<br/>MinIO / external S3")]
25
+ reg[("registry<br/>deploy images")]
26
+ s2[("s2 / s2-lite<br/>realtime streams v2")]
27
+
28
+ webapp --> pg
29
+ webapp --> redis
30
+ webapp --> ch
31
+ webapp --> obj
32
+ webapp --> s2
33
+ webapp -->|worker token| supervisor
34
+ supervisor --> workers
35
+ workers --> reg
36
+ ```
37
+
38
+ Each component maps to a top-level key in `values.yaml`: `webapp`, `supervisor`, `postgres`, `redis`, `electric`, `clickhouse`, `s3` (object storage), `s2`, and `registry`. The datastores default to `deploy: true` and run in-cluster; set `deploy: false` with an `external` block to bring your own. The registry is the exception - it defaults to `deploy: false`, so you point it at an external one. Webapp settings live under `webapp`, supervisor settings under `supervisor.config`, and each service takes `extraEnvVars` for anything else.
13
39
 
14
40
  ## Requirements
15
41
 
@@ -52,57 +78,111 @@ webapp:
52
78
  memory: 4Gi
53
79
  ```
54
80
 
55
- ## Installation
81
+ ## Evaluation install
82
+
83
+ Bundled datastores let you run the whole stack with a single command and no external services. The default values are insecure and are only suitable for testing - for real workloads, follow the [production install](#production-install) instead.
84
+
85
+ <Steps>
86
+ <Step title="Install the chart with default values">
87
+ ```bash
88
+ helm upgrade -n trigger --install trigger \
89
+ oci://ghcr.io/triggerdotdev/charts/trigger \
90
+ --version "^4.5.0" \
91
+ --create-namespace
92
+ ```
93
+
94
+ The chart deploys the webapp, supervisor, and bundled Postgres, Redis, Electric, ClickHouse, MinIO, and s2-lite. The registry is not deployed by default - configure an external one before deploying tasks.
95
+ </Step>
56
96
 
57
- ### Quick start
97
+ <Step title="Port-forward the webapp">
98
+ ```bash
99
+ kubectl port-forward svc/trigger-webapp 3040:3030 -n trigger
100
+ ```
58
101
 
59
- 1. Install with default values (for testing only):
102
+ The dashboard is now reachable at `http://localhost:3040`.
103
+ </Step>
104
+
105
+ <Step title="Log in with the magic link">
106
+ Default installs print the login link to the webapp logs instead of sending email.
107
+
108
+ ```bash
109
+ kubectl logs -n trigger deployment/trigger-webapp | grep -A1 "magic link"
110
+ ```
111
+
112
+ Open the printed link to sign in.
113
+ </Step>
114
+ </Steps>
115
+
116
+ ### Verify it
117
+
118
+ Confirm every component reached a healthy state:
60
119
 
61
120
  ```bash
62
- helm upgrade -n trigger --install trigger \
63
- oci://ghcr.io/triggerdotdev/charts/trigger \
64
- --version "^4.5.0" \
65
- --create-namespace
121
+ kubectl get pods -n trigger
66
122
  ```
67
123
 
68
- 2. Access the webapp:
124
+ The webapp, supervisor, and each bundled datastore pod should report `Running` with all containers `READY`. Migrations and bootstrap run inside the webapp pod rather than as separate jobs, so if the webapp stays unready, check its logs. If a pod is stuck in `Pending` or `CrashLoopBackOff`, jump to [Troubleshooting](#troubleshooting).
69
125
 
70
- ```bash
71
- kubectl port-forward svc/trigger-webapp 3040:3030 -n trigger
126
+ Once you can sign in and trigger a run, you've validated the stack. For a deployment that survives restarts, upgrades, and load, move on to the production install.
127
+
128
+ ## Production install
129
+
130
+ Running external datastores is the requirement that separates a production install from an evaluation one. You supply your own Postgres, Redis, ClickHouse, and object storage, manage secrets yourself, and point the chart at each service. The steps below layer onto the same `helm upgrade` command, driven by a custom values file.
131
+
132
+ ### Secrets
133
+
134
+ Application, control-plane, and bundled-datastore secrets left unset are generated on first install and **retained across `helm upgrade`** - they are never rotated automatically, so sessions, encrypted data, and datastore volumes survive upgrades. This auto-generation is the default and needs no configuration.
135
+
136
+ For production, supply your own Secret instead so credentials live outside the release. With `secrets.existingSecret` set, the chart generates nothing and reads every key from your Secret; a preflight check fails the install - before touching a running release - and lists any keys it can't find.
137
+
138
+ To pin values inline instead of letting the chart generate them - for example to share `MANAGED_WORKER_SECRET` with an external supervisor - set them under `secrets`:
139
+
140
+ ```yaml
141
+ secrets:
142
+ enabled: true
143
+ sessionSecret: "your-32-char-hex-secret-1"
144
+ magicLinkSecret: "your-32-char-hex-secret-2"
145
+ # ...
72
146
  ```
73
147
 
74
- 3. Open the dashboard: `http://localhost:3040`
148
+ To use an existing Secret instead, leave the values unset and set `existingSecret`. It must contain at least `SESSION_SECRET`, `MAGIC_LINK_SECRET`, `ENCRYPTION_KEY`, `PROVIDER_SECRET`, `COORDINATOR_SECRET`, and `MANAGED_WORKER_SECRET` - plus `s3-auth-access-key-id` and `s3-auth-secret-access-key` if you deploy the bundled MinIO with `s3.auth.existingSecret` cleared:
149
+
150
+ ```yaml
151
+ secrets:
152
+ enabled: false
153
+ existingSecret: "your-existing-secret"
154
+ ```
75
155
 
76
- 4. Login with the magic link:
156
+ The chart wires `PROVIDER_SECRET` and `COORDINATOR_SECRET` into the webapp deployment, and the pre-upgrade check requires both, so an existing Secret must include them. For a deployment that already runs, add them before upgrading:
77
157
 
78
158
  ```bash
79
- # Check the webapp logs
80
- kubectl logs -n trigger deployment/trigger-webapp | grep -A1 "magic link"
159
+ kubectl patch secret my-trigger-secrets -n trigger --type merge -p \
160
+ "{\"stringData\":{\"PROVIDER_SECRET\":\"$(openssl rand -hex 16)\",\"COORDINATOR_SECRET\":\"$(openssl rand -hex 16)\"}}"
81
161
  ```
82
162
 
83
- ## Configuration
163
+ There is no clean migration for a compromised `ENCRYPTION_KEY`: changing it makes existing encrypted data unreadable. If a deployment is still running a previously published default and cannot rotate yet, set `ALLOW_INSECURE_DEFAULT_SECRETS=true` on the webapp to keep booting while you plan a migration.
84
164
 
85
- 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.
86
-
87
- **Naming convention:**
165
+ <Warning>
166
+ GitOps tools that render with `helm template` (e.g. Argo CD) cannot read the existing
167
+ secret, so they regenerate auto-generated values on every sync - which rotates them. If you
168
+ deploy via GitOps, always supply your own `secrets.existingSecret` (and datastore
169
+ credentials) so nothing is generated in-cluster.
170
+ </Warning>
88
171
 
89
- - Environment variables use `UPPER_SNAKE_CASE`
90
- - Helm values use `camelCase`
172
+ ### Custom values
91
173
 
92
- **Example mapping:**
174
+ 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. Environment variables use `UPPER_SNAKE_CASE`; Helm values use `camelCase`:
93
175
 
94
176
  ```bash
95
177
  # Environment variable
96
178
  APP_ORIGIN=https://trigger.example.com
97
179
 
98
180
  # Becomes Helm value
99
- config:
181
+ webapp:
100
182
  appOrigin: "https://trigger.example.com"
101
183
  ```
102
184
 
103
- ### Default values
104
-
105
- The following commands will display the default values:
185
+ Print the full default surface for the version you're deploying:
106
186
 
107
187
  ```bash
108
188
  # Specific version
@@ -114,44 +194,14 @@ helm show values oci://ghcr.io/triggerdotdev/charts/trigger \
114
194
  --version "^4.5.0"
115
195
  ```
116
196
 
117
- ### Custom values
118
-
119
- The default values are insecure and are only suitable for testing. You will need to configure your own secrets as a bare minimum.
120
-
121
- Create a `values-custom.yaml` file to override the defaults. For example:
197
+ Create a `values-custom.yaml` that overrides the defaults with your URLs and resource requests:
122
198
 
123
199
  ```yaml
124
- # Leave these unset to have the chart auto-generate strong values on first
125
- # install (retained across upgrades). Set them explicitly only if you need to
126
- # control the value - e.g. sharing MANAGED_WORKER_SECRET with an external
127
- # supervisor - or use an existingSecret.
128
- secrets:
129
- enabled: true
130
- sessionSecret: "your-32-char-hex-secret-1"
131
- magicLinkSecret: "your-32-char-hex-secret-2"
132
- # ...
133
-
134
- # Recommended: existingSecret, must contain at least the following keys:
135
- # - SESSION_SECRET
136
- # - MAGIC_LINK_SECRET
137
- # - ENCRYPTION_KEY
138
- # - PROVIDER_SECRET
139
- # - COORDINATOR_SECRET
140
- # - MANAGED_WORKER_SECRET
141
- # - OBJECT_STORE_ACCESS_KEY_ID
142
- # - OBJECT_STORE_SECRET_ACCESS_KEY
143
- secrets:
144
- enabled: false
145
- existingSecret: "your-existing-secret"
146
-
147
- # Application URLs
148
- config:
200
+ # Application URLs and resource limits
201
+ webapp:
149
202
  appOrigin: "https://trigger.example.com"
150
203
  loginOrigin: "https://trigger.example.com"
151
204
  apiOrigin: "https://trigger.example.com"
152
-
153
- # Resource limits
154
- webapp:
155
205
  resources:
156
206
  requests:
157
207
  cpu: 1000m
@@ -180,27 +230,7 @@ helm upgrade -n trigger --install trigger \
180
230
  -f values-custom.yaml
181
231
  ```
182
232
 
183
- ### Secret generation and rotation
184
-
185
- Application, control-plane, and bundled-datastore secrets left unset are generated on
186
- first install and **retained across `helm upgrade`** - they are never rotated
187
- automatically, so sessions, encrypted data, and datastore volumes survive upgrades.
188
-
189
- <Warning>
190
- GitOps tools that render with `helm template` (e.g. Argo CD) cannot read the existing
191
- secret, so they regenerate these values on every sync - which rotates them. If you
192
- deploy via GitOps, always supply your own `secrets.existingSecret` (and datastore
193
- credentials) so nothing is generated in-cluster.
194
- </Warning>
195
-
196
- There is no clean migration for a compromised `ENCRYPTION_KEY`: changing it makes
197
- existing encrypted data unreadable. If a deployment is still running a previously
198
- published default and cannot rotate yet, set `ALLOW_INSECURE_DEFAULT_SECRETS=true` on
199
- the webapp to keep booting while you plan a migration.
200
-
201
- ### Extra env
202
-
203
- You can set extra environment variables on all services. For example:
233
+ Set extra environment variables on any service:
204
234
 
205
235
  ```yaml
206
236
  webapp:
@@ -209,9 +239,7 @@ webapp:
209
239
  value: "extra-value"
210
240
  ```
211
241
 
212
- ### Extra annotations
213
-
214
- You can set extra annotations on all services. For example:
242
+ Set extra annotations on any service:
215
243
 
216
244
  ```yaml
217
245
  webapp:
@@ -221,7 +249,7 @@ webapp:
221
249
 
222
250
  ### External services
223
251
 
224
- You can disable the built-in services and use external services instead. The chart supports both direct configuration and existing Kubernetes secrets for secure credential management.
252
+ Disable each built-in datastore and point the chart at your own. Every service supports direct configuration or an existing Kubernetes secret; use existing secrets to keep credentials out of `values.yaml` and Helm releases.
225
253
 
226
254
  #### PostgreSQL
227
255
 
@@ -279,6 +307,13 @@ redis:
279
307
 
280
308
  #### ClickHouse
281
309
 
310
+ Migration from the old Bitnami subchart to the official `clickhouse/clickhouse-server` image is automatic - a normal upgrade moves you across with no manual step. The one exception: if you pinned `clickhouse.image` to a Bitnami tag, switch it to an official `clickhouse/clickhouse-server` tag first, since Bitnami tags don't exist in the official repository.
311
+
312
+ <Note>
313
+ Trigger.dev requires ClickHouse 25.8 or newer. The bundled ClickHouse is single-node — run
314
+ ClickHouse externally for a clustered or replicated setup.
315
+ </Note>
316
+
282
317
  **Direct configuration:**
283
318
 
284
319
  ```yaml
@@ -286,11 +321,17 @@ clickhouse:
286
321
  deploy: false
287
322
  external:
288
323
  host: "my-clickhouse.example.com"
289
- port: 8123
324
+ httpPort: 8123
290
325
  username: "my-username"
291
326
  password: "my-password"
292
327
  ```
293
328
 
329
+ <Note>
330
+ An inline external `username`/`password` is percent-encoded into the connection URL for you, so
331
+ store the **raw** value - special characters like `@ : / %` are handled automatically.
332
+ (Credentials from `existingSecret` are injected at runtime and are unaffected.)
333
+ </Note>
334
+
294
335
  **Using existing secrets (recommended):**
295
336
 
296
337
  ```yaml
@@ -298,20 +339,21 @@ clickhouse:
298
339
  deploy: false
299
340
  external:
300
341
  host: "my-clickhouse.example.com"
301
- port: 8123
342
+ httpPort: 8123
302
343
  username: "my-username"
303
344
  existingSecret: "clickhouse-credentials"
304
345
  # existingSecretKey: "clickhouse-password" # default (optional)
305
346
  ```
306
347
 
307
- #### S3 Object Storage
348
+ #### Object storage
349
+
350
+ Object storage holds deploy artifacts and large payloads. See the [Docker object storage setup](/self-hosting/docker#object-storage) for conceptual information. Disable the bundled MinIO and point at any S3-compatible endpoint.
308
351
 
309
352
  **Direct configuration:**
310
353
 
311
354
  ```yaml
312
- minio:
313
- deploy: false
314
355
  s3:
356
+ deploy: false
315
357
  external:
316
358
  endpoint: "https://s3.amazonaws.com"
317
359
  accessKeyId: "my-access-key"
@@ -321,21 +363,19 @@ s3:
321
363
  **Using existing secrets (recommended):**
322
364
 
323
365
  ```yaml
324
- minio:
325
- deploy: false
326
366
  s3:
367
+ deploy: false
327
368
  external:
328
369
  endpoint: "https://s3.amazonaws.com"
329
370
  existingSecret: "s3-credentials"
330
- # Optional: Use secretKeys to specify the key names in the secret
331
- # secretKeys:
332
- # accessKeyIdKey: "access-key-id" # default
333
- # secretAccessKeyKey: "secret-access-key" # default
371
+ # Optional: override the key names in the secret
372
+ # existingSecretAccessKeyIdKey: "access-key-id" # default
373
+ # existingSecretSecretAccessKeyKey: "secret-access-key" # default
334
374
  ```
335
375
 
336
376
  ### PostgreSQL SSL with custom CA certificates
337
377
 
338
- When connecting to PostgreSQL instances that require custom CA certificates (such as AWS RDS with SSL verification), you can mount the CA certificate as a volume and configure the webapp to use it:
378
+ When connecting to PostgreSQL instances that require custom CA certificates (such as AWS RDS with SSL verification), mount the CA certificate as a volume and configure the webapp to use it:
339
379
 
340
380
  ```yaml
341
381
  postgres:
@@ -376,99 +416,9 @@ webapp:
376
416
  - Compatible with secret management tools (External Secrets Operator, etc.)
377
417
  - Follows Kubernetes security best practices
378
418
 
379
- ## DNS performance
380
-
381
- For production clusters we recommend deploying [NodeLocal DNSCache](https://kubernetes.io/docs/tasks/administer-cluster/nodelocaldns/). DNS queries — especially to managed Postgres or Redis endpoints — can be very slow under Kubernetes' default resolver, and a node-local cache typically gives a large step change in latency and throughput across the cluster.
382
-
383
- The default `ndots: 5` setting also forces every cluster search domain to be tried before resolving hostnames with fewer dots (the case for most external database hosts). Lowering `ndots` to `1` on the webapp and supervisor pods avoids those extra round-trips.
384
-
385
- ## Task events
386
-
387
- By default, task events (timeline, logs, spans) are stored in PostgreSQL. For production deployments we recommend storing them in ClickHouse instead, it scales to much higher volumes and avoids unbounded growth of the `TaskEvent` table.
388
-
389
- ClickHouse is already deployed by the chart, so no extra services are required. To enable, set `EVENT_REPOSITORY_DEFAULT_STORE` on the webapp via `extraEnvVars`:
390
-
391
- ```yaml
392
- webapp:
393
- extraEnvVars:
394
- - name: EVENT_REPOSITORY_DEFAULT_STORE
395
- value: "clickhouse_v2"
396
- ```
397
-
398
- This only affects new runs; existing runs continue to read from wherever their events were originally stored.
399
-
400
- ## Realtime streams
401
-
402
- Realtime streams power AI-agent token streaming and run streams. They default to **v2**, backed by the bundled `s2` deployment — [s2-lite](https://s2.dev), the open-source, self-hostable S2 server. The chart deploys it with a persistent volume, so no extra services are required.
403
-
404
- To fall back to the Redis-backed **v1** streams, set the default version to `v1`:
405
-
406
- ```yaml
407
- s2:
408
- defaultStreamVersion: "v1"
409
- ```
410
-
411
- To use a hosted S2 at [s2.dev](https://s2.dev) instead of the bundled s2-lite, disable the bundled deployment and point at your basin. Supply the access token via an existing secret:
412
-
413
- ```yaml
414
- s2:
415
- deploy: false
416
- skipAccessTokens: false
417
- external:
418
- endpoint: "https://your-basin.b.aws.s2.dev/v1"
419
- existingSecret: "s2-credentials"
420
- existingSecretAccessTokenKey: "access-token"
421
- basin: "your-basin"
422
- ```
423
-
424
- To disable realtime streams v2 entirely and use v1, set `s2.deploy: false` with no external endpoint. See `helm show values` for all `s2` options.
425
-
426
- ## Worker token
427
-
428
- When using the default bootstrap configuration, worker creation and authentication is handled automatically. The webapp generates a worker token and makes it available to the supervisor via a shared volume.
429
-
430
- ### Bootstrap (default)
431
-
432
- ```yaml
433
- webapp:
434
- bootstrap:
435
- enabled: true
436
- workerGroupName: "bootstrap"
437
- ```
438
-
439
- ### Manual
440
-
441
- If you need to set up workers separately or use a custom token:
442
-
443
- 1. Get the worker token from the webapp logs:
444
-
445
- ```bash
446
- kubectl logs deployment/trigger-webapp -n trigger | grep -A15 "Worker Token"
447
- ```
448
-
449
- 2. Create a secret with the token:
450
-
451
- ```bash
452
- kubectl create secret generic worker-token \
453
- --from-literal=token=tr_wgt_your_token_here \
454
- -n trigger
455
- ```
419
+ ### Registry setup
456
420
 
457
- 3. Configure the supervisor to use the secret:
458
-
459
- ```yaml
460
- supervisor:
461
- bootstrap:
462
- enabled: false
463
- workerToken:
464
- secret:
465
- name: "worker-token"
466
- key: "token"
467
- ```
468
-
469
- ## Registry setup
470
-
471
- See the [Docker registry setup](/self-hosting/docker#registry-setup) for conceptual information. The configuration is specified in your `values.yaml`:
421
+ Built deploy images are pushed to a registry. See the [Docker registry setup](/self-hosting/docker#registry-setup) for conceptual information. Configure an external registry in your `values.yaml`:
472
422
 
473
423
  ```yaml
474
424
  # Use external registry (recommended)
@@ -477,8 +427,7 @@ registry:
477
427
  # Part of deployment image ref, for example: your-registry.example.com/your-company/proj_123:20250625.1.prod
478
428
  repositoryNamespace: "your-company"
479
429
  external:
480
- host: "your-registry.example.com"
481
- port: 5000
430
+ host: "your-registry.example.com:5000"
482
431
  auth:
483
432
  enabled: true
484
433
  username: "your-username"
@@ -486,32 +435,19 @@ registry:
486
435
  ```
487
436
 
488
437
  <Note>
489
- The internal registry (`registry.external: false`) is experimental and requires proper TLS setup
438
+ The internal registry (`registry.deploy: true`) is experimental and requires proper TLS setup
490
439
  and additional cluster configuration. Use an external registry for production.
491
440
  </Note>
492
441
 
493
- ## Object storage
494
-
495
- See the [Docker object storage setup](/self-hosting/docker#object-storage) for conceptual information. The defaults will use built-in MinIO, but you can use an external S3-compatible storage. The configuration is specified in your `values.yaml`:
442
+ ### DNS performance
496
443
 
497
- ```yaml
498
- # Use external S3-compatible storage
499
- minio:
500
- deploy: false
501
- external:
502
- url: "https://s3.amazonaws.com"
503
- # or: "https://your-minio.com:9000"
444
+ For production clusters we recommend deploying [NodeLocal DNSCache](https://kubernetes.io/docs/tasks/administer-cluster/nodelocaldns/). DNS queries — especially to managed Postgres or Redis endpoints — can be very slow under Kubernetes' default resolver, and a node-local cache typically gives a large step change in latency and throughput across the cluster.
504
445
 
505
- # Configure credentials
506
- secrets:
507
- objectStore:
508
- accessKeyId: "admin"
509
- secretAccessKey: "very-safe-password"
510
- ```
446
+ The default `ndots: 5` setting also forces every cluster search domain to be tried before resolving hostnames with fewer dots (the case for most external database hosts). Lowering `ndots` to `1` on the webapp and supervisor pods avoids those extra round-trips.
511
447
 
512
- ## Authentication
448
+ ### Authentication
513
449
 
514
- Authentication options are identical to the [Docker-based installation](/self-hosting/docker#authentication). The configuration is specified in your `values.yaml`:
450
+ Authentication options are identical to the [Docker-based installation](/self-hosting/docker#authentication). Configure the provider in your `values.yaml`:
515
451
 
516
452
  **GitHub OAuth:**
517
453
 
@@ -548,7 +484,91 @@ webapp:
548
484
  value: "^(user1@company\\.com|user2@company\\.com)$"
549
485
  ```
550
486
 
551
- ## Version locking
487
+ ### Worker token
488
+
489
+ The supervisor authenticates to the webapp with a worker token. The default bootstrap path generates one for you; supply your own token to manage workers separately.
490
+
491
+ **Bootstrap (default):** the webapp generates a worker token and makes it available to the supervisor via a shared volume.
492
+
493
+ ```yaml
494
+ webapp:
495
+ bootstrap:
496
+ enabled: true
497
+ workerGroupName: "bootstrap"
498
+ ```
499
+
500
+ **Manual:** to set up workers separately or use a custom token:
501
+
502
+ <Steps>
503
+ <Step title="Read the worker token from the webapp logs">
504
+ ```bash
505
+ kubectl logs deployment/trigger-webapp -n trigger | grep -A15 "Worker Token"
506
+ ```
507
+ </Step>
508
+
509
+ <Step title="Create a secret with the token">
510
+ ```bash
511
+ kubectl create secret generic worker-token \
512
+ --from-literal=token=tr_wgt_your_token_here \
513
+ -n trigger
514
+ ```
515
+ </Step>
516
+
517
+ <Step title="Point the supervisor at the secret">
518
+ ```yaml
519
+ supervisor:
520
+ bootstrap:
521
+ enabled: false
522
+ workerToken:
523
+ secret:
524
+ name: "worker-token"
525
+ key: "token"
526
+ ```
527
+ </Step>
528
+ </Steps>
529
+
530
+ With external datastores, secrets, registry, and authentication in place, you have a production install. If you only wanted to try Trigger.dev, the [evaluation install](#evaluation-install) gets you there in one command.
531
+
532
+ ## Operating your deployment
533
+
534
+ ### Upgrading
535
+
536
+ `helm upgrade` is safe to run as-is. Your generated secrets, data volumes, and the bundled ClickHouse are preserved and migrated automatically, so a normal upgrade needs no preparation. A few situations need one manual step first — expand any that apply to you.
537
+
538
+ <AccordionGroup>
539
+ <Accordion title="You supply your own secret (secrets.existingSecret)">
540
+ With `secrets.existingSecret` set, the chart reads every key from your Secret and generates none, so any key the app needs must already be present there.
541
+
542
+ As of chart 4.5.6 the webapp deployment references `PROVIDER_SECRET` and `COORDINATOR_SECRET`, and the pre-upgrade check requires both, so an existing Secret must carry them. Add both before upgrading:
543
+
544
+ ```bash
545
+ kubectl patch secret my-trigger-secrets -n trigger --type merge -p \
546
+ "{\"stringData\":{\"PROVIDER_SECRET\":\"$(openssl rand -hex 16)\",\"COORDINATOR_SECRET\":\"$(openssl rand -hex 16)\"}}"
547
+ ```
548
+
549
+ If a required key is missing, the upgrade stops before touching your running release and tells you which to add.
550
+ </Accordion>
551
+
552
+ <Accordion title="Something outside the chart reads a datastore password">
553
+ The bundled datastore passwords live in the `trigger-datastore` Secret. If a maintenance job, a dashboard, or a secret sync reads one directly, point it there:
554
+
555
+ ```bash
556
+ kubectl get secret trigger-datastore -n trigger \
557
+ -o jsonpath='{.data.clickhouse-admin-password}' | base64 -d
558
+ ```
559
+
560
+ The keys are `clickhouse-admin-password`, `postgres-password`, and `minio-root-user` / `minio-root-password`.
561
+ </Accordion>
562
+
563
+ <Accordion title="You render manifests without cluster access (Argo CD, plain helm template)">
564
+ During an upgrade the chart reads the cluster to keep your data and to check your Secret. Renderers that run offline can't do that, so set these yourself:
565
+
566
+ - Point `clickhouse.persistence.existingClaim` at your ClickHouse data volume (`data-<release>-clickhouse-shard0-0`) and keep it set on future syncs, so ClickHouse reuses its data instead of starting on an empty volume.
567
+ - Confirm `PROVIDER_SECRET` and `COORDINATOR_SECRET` are already in your Secret before syncing.
568
+ </Accordion>
569
+ </AccordionGroup>
570
+
571
+ ### Version locking
552
572
 
553
573
  <Note>
554
574
  Trigger.dev 4.5.0 is the last version we officially support for running v3 (SDK v3) tasks. If
@@ -556,7 +576,7 @@ webapp:
556
576
  later reject v3 triggers and deploys with an upgrade message.
557
577
  </Note>
558
578
 
559
- You can lock versions in two ways:
579
+ Lock versions in two ways.
560
580
 
561
581
  **Helm chart version (recommended):**
562
582
 
@@ -588,7 +608,7 @@ supervisor:
588
608
 
589
609
  The chart version's `appVersion` field determines the default image tags. Newer image tags may be incompatible with older chart versions and vice versa.
590
610
 
591
- ## Troubleshooting
611
+ ### Troubleshooting
592
612
 
593
613
  **Check logs:**
594
614
 
@@ -633,18 +653,58 @@ kubectl delete namespace trigger
633
653
 
634
654
  See the [Docker troubleshooting](/self-hosting/docker#troubleshooting) section for more information.
635
655
 
636
- ## CLI usage
656
+ ### Task events
657
+
658
+ By default, task events (timeline, logs, spans) are stored in PostgreSQL. For production deployments we recommend storing them in ClickHouse instead, it scales to much higher volumes and avoids unbounded growth of the `TaskEvent` table.
659
+
660
+ ClickHouse is already deployed by the chart, so no extra services are required. To enable, set `EVENT_REPOSITORY_DEFAULT_STORE` on the webapp via `extraEnvVars`:
661
+
662
+ ```yaml
663
+ webapp:
664
+ extraEnvVars:
665
+ - name: EVENT_REPOSITORY_DEFAULT_STORE
666
+ value: "clickhouse_v2"
667
+ ```
668
+
669
+ This only affects new runs; existing runs continue to read from wherever their events were originally stored.
670
+
671
+ ### Realtime streams
672
+
673
+ Realtime streams power AI-agent token streaming and run streams. They default to **v2**, backed by the bundled `s2` deployment — [s2-lite](https://s2.dev), the open-source, self-hostable S2 server. The chart deploys it with a persistent volume, so no extra services are required.
674
+
675
+ To fall back to the Redis-backed **v1** streams, set the default version to `v1`:
676
+
677
+ ```yaml
678
+ s2:
679
+ defaultStreamVersion: "v1"
680
+ ```
681
+
682
+ To use a hosted S2 at [s2.dev](https://s2.dev) instead of the bundled s2-lite, disable the bundled deployment and point at your basin. Supply the access token via an existing secret:
683
+
684
+ ```yaml
685
+ s2:
686
+ deploy: false
687
+ skipAccessTokens: false
688
+ external:
689
+ endpoint: "https://your-basin.b.aws.s2.dev/v1"
690
+ existingSecret: "s2-credentials"
691
+ existingSecretAccessTokenKey: "access-token"
692
+ basin: "your-basin"
693
+ ```
694
+
695
+ To disable realtime streams v2 entirely and use v1, set `s2.deploy: false` with no external endpoint. See `helm show values` for all `s2` options.
696
+
697
+ ### CLI usage
637
698
 
638
699
  See the [Docker CLI usage](/self-hosting/docker#cli-usage) section, the commands are identical regardless of deployment method.
639
700
 
640
- ## CI / GitHub Actions
701
+ ### CI / GitHub Actions
641
702
 
642
- When running the CLI in a CI environment, your login profiles won't be available. Instead, you can use the `TRIGGER_API_URL` and `TRIGGER_ACCESS_TOKEN` environment
643
- variables to point at your self-hosted instance and authenticate.
703
+ When running the CLI in a CI environment, your login profiles won't be available. Instead, use the `TRIGGER_API_URL` and `TRIGGER_ACCESS_TOKEN` environment variables to point at your self-hosted instance and authenticate.
644
704
 
645
705
  For more detailed instructions, see the [GitHub Actions guide](/github-actions).
646
706
 
647
- ## Telemetry
707
+ ### Telemetry
648
708
 
649
709
  By default, the Trigger.dev webapp sends telemetry data to our servers. This data is used to improve the product and is not shared with third parties. To disable telemetry, set in your `values.yaml`:
650
710