@@ -4,6 +4,7 @@ import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'
44import { resourceFromAttributes } from '@opentelemetry/resources'
55import { createLogger } from '@sim/logger'
66import { distrustCompromisedRoots } from '@sim/security/tls-trust'
7+ import type { BuildExtension } from '@trigger.dev/build'
78import {
89 additionalFiles ,
910 additionalPackages ,
@@ -65,6 +66,42 @@ function getFunctionExecutionEnvVars() {
6566 } )
6667}
6768
69+ /**
70+ * Node.js version copied into the task image, in lockstep with `NODE_VERSION`
71+ * in `docker/app.Dockerfile`: `isolated-vm` 6.x loads its Node 24 (ABI 137)
72+ * prebuild. The image is pinned by its multi-arch index digest.
73+ */
74+ const NODE_VERSION = '24.22.1'
75+ const NODE_IMAGE = `node:${ NODE_VERSION } -bookworm-slim@sha256:be8204d4bd327363357f532187b752ff62759c31bedf98e9e18fc08c9cbd605c`
76+
77+ /**
78+ * Tasks run on Bun, but the `bun-1.4` image ships no `node`, and the
79+ * isolated-vm sandbox worker and the Oracle Database worker are spawned as
80+ * `node` child processes, the same split as the app image. Adding image
81+ * instructions also builds the install stage from this base, so `bun install`
82+ * runs `isolated-vm`'s install script against the same Node. Deploy only:
83+ * `trigger dev` spawns the developer's own `node`.
84+ *
85+ * @see https://trigger.dev/docs/guides/frameworks/bun#choosing-a-bun-runtime
86+ */
87+ function nodeBinary ( ) : BuildExtension {
88+ return {
89+ name : 'node-binary' ,
90+ onBuildComplete ( context ) {
91+ if ( context . target === 'dev' ) return
92+ context . addLayer ( {
93+ id : 'node-binary' ,
94+ image : {
95+ instructions : [
96+ `COPY --from=${ NODE_IMAGE } /usr/local/bin/node /usr/local/bin/node` ,
97+ `RUN [ "$(node --version)" = "v${ NODE_VERSION } " ]` ,
98+ ] ,
99+ } ,
100+ } )
101+ } ,
102+ }
103+ }
104+
68105const grafanaTelemetry = grafanaFullyConfigured
69106 ? ( ( ) => {
70107 const baseUrl = grafanaEndpoint ! . replace ( / \/ + $ / , '' )
@@ -88,7 +125,7 @@ const grafanaTelemetry = grafanaFullyConfigured
88125
89126export default defineConfig ( {
90127 project : env . TRIGGER_PROJECT_ID ! ,
91- runtime : 'node-24 ' ,
128+ runtime : 'bun-1.4 ' ,
92129 logLevel : 'info' ,
93130 maxDuration : 5400 ,
94131 retries : {
@@ -159,6 +196,7 @@ export default defineConfig({
159196 'sharp' ,
160197 ] ,
161198 extensions : [
199+ nodeBinary ( ) ,
162200 syncEnvVars ( ( ) => [
163201 { name : 'DB_APP_NAME' , value : 'sim-trigger' } ,
164202 /**
0 commit comments