Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .server-changes/runtime-api-origin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
area: webapp
type: feature
---

Add `RUNTIME_API_ORIGIN` env var to route managed runner traffic through an in-cluster URL, bypassing tracing gateways that rewrite the W3C `traceparent` header and break parent→child run links.
15 changes: 15 additions & 0 deletions apps/webapp/app/env.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,21 @@ const EnvironmentSchema = z
LOGIN_RATE_LIMITS_ENABLED: BoolEnv.default(true),
APP_ORIGIN: z.string().default("http://localhost:3030"),
API_ORIGIN: z.string().optional(),
// Origin that the webapp publishes to MANAGED (deployed) runner pods as
// both `TRIGGER_API_URL` and (as the first fallback) `TRIGGER_STREAM_URL`.
// When self-hosting behind a tracing-enabled gateway (Envoy/Istio/etc.)
// that rewrites the W3C `traceparent` on egress, point this at an
// in-cluster service URL so runner-to-webapp traffic stays inside the
// cluster and the parent->child run link in the trace tree is preserved.
// Intentionally NOT used for dev (CLI) task runs, which usually run on a
// developer's machine outside the cluster and would lose connectivity if
// forced onto an in-cluster URL. Empty string is normalized to unset so
// blank `${RUNTIME_API_ORIGIN:-}` passthroughs from caller environments
// don't short-circuit the `??` fallback chain.
RUNTIME_API_ORIGIN: z
.string()
.optional()
.transform((v) => v || undefined),
Comment thread
devin-ai-integration[bot] marked this conversation as resolved.
STREAM_ORIGIN: z.string().optional(),
ELECTRIC_ORIGIN: z.string().default("http://localhost:3060"),
// A comma separated list of electric origins to shard into different electric instances by environmentId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -980,6 +980,13 @@ function renameVariables(variables: EnvironmentVariable[], renameMap: Record<str
});
}

/**
* Resolves trigger-side built-in environment variables that are merged into a
* task run's env but can be overridden by user-defined variables on the
* environment. Values come from server-level `env` and are surfaced to runners
* so they can pick up rollouts (e.g. the realtime stream version) without a
* redeploy.
*/
async function resolveOverridableTriggerVariables(
runtimeEnvironment: RuntimeEnvironmentForEnvRepo
) {
Expand All @@ -993,6 +1000,14 @@ async function resolveOverridableTriggerVariables(
return result;
}

/**
* Resolves built-in environment variables that are injected into dev (CLI) task
* runs. Dev CLI typically runs on a developer's machine outside any cluster,
* so the runner-bypass `RUNTIME_API_ORIGIN` (which usually points at an
* in-cluster service URL) is intentionally NOT applied here -- using it would
* make the URL unreachable for the dev CLI. Dev keeps the original
* `API_ORIGIN`/`STREAM_ORIGIN`/`APP_ORIGIN` chain.
*/
async function resolveBuiltInDevVariables(runtimeEnvironment: RuntimeEnvironmentForEnvRepo) {
let result: Array<EnvironmentVariable> = [
{
Expand Down Expand Up @@ -1119,6 +1134,12 @@ async function resolveBuiltInDevVariables(runtimeEnvironment: RuntimeEnvironment
return [...result, ...commonVariables];
}

/**
* Resolves the OpenTelemetry collector endpoint advertised to dev (CLI) task
* runs. Defaults to the webapp's own `/otel` route under `APP_ORIGIN` so a
* vanilla self-host works without extra wiring; `DEV_OTEL_EXPORTER_OTLP_ENDPOINT`
* can override it to point spans/logs at an external collector.
*/
async function resolveOverridableOtelDevVariables(
runtimeEnvironment: RuntimeEnvironmentForEnvRepo
) {
Expand All @@ -1132,6 +1153,15 @@ async function resolveOverridableOtelDevVariables(
return result;
}

/**
* Resolves built-in environment variables that are injected into managed
* (deployed) task runs. `TRIGGER_API_URL` and `TRIGGER_STREAM_URL` prefer
* `RUNTIME_API_ORIGIN` over `API_ORIGIN`/`STREAM_ORIGIN` so self-hosted
* deployments can keep runner-to-webapp traffic on a cluster-internal hop
* (bypassing tracing-enabled gateways that rewrite the W3C `traceparent`
* header on egress) without affecting the public origins exposed to external
* clients.
*/
async function resolveBuiltInProdVariables(
runtimeEnvironment: RuntimeEnvironmentForEnvRepo,
parentEnvironment?: RuntimeEnvironmentForEnvRepo
Expand All @@ -1143,11 +1173,11 @@ async function resolveBuiltInProdVariables(
},
{
key: "TRIGGER_API_URL",
value: env.API_ORIGIN ?? env.APP_ORIGIN,
value: env.RUNTIME_API_ORIGIN ?? env.API_ORIGIN ?? env.APP_ORIGIN,
},
{
key: "TRIGGER_STREAM_URL",
value: env.STREAM_ORIGIN ?? env.API_ORIGIN ?? env.APP_ORIGIN,
value: env.RUNTIME_API_ORIGIN ?? env.STREAM_ORIGIN ?? env.API_ORIGIN ?? env.APP_ORIGIN,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here RUNTIME_API_ORIGIN wins over an explicitly-set STREAM_ORIGIN for managed runners, making them mutually exclusive. Looks deliberate (and the reorder would re-expose the stream path to the gateway this bypasses), but a one-line comment on why stream follows the runner origin first would make the precedence easy to accept at a glance.

},
{
key: "TRIGGER_RUNTIME_WAIT_THRESHOLD_IN_MS",
Expand Down
10 changes: 10 additions & 0 deletions hosting/docker/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@ API_ORIGIN=http://localhost:8030
DEV_OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:8030/otel
# You may need to set this when testing locally or when using the combined setup
# API_ORIGIN=http://webapp:3000
# Optional: origin advertised to MANAGED (deployed) runner pods as both
# TRIGGER_API_URL and TRIGGER_STREAM_URL (intentional: keeps all managed
# runner traffic on the same bypass hop). Dev (CLI) task runs are NOT
# affected -- they keep using API_ORIGIN/APP_ORIGIN so a developer running
# `trigger.dev dev` from outside the cluster doesn't lose connectivity.
# Set this to an in-cluster service URL when running behind a tracing-enabled
# gateway that rewrites the W3C `traceparent` header on egress (e.g. Envoy/
# Istio with tracing on). If you need streams on a dedicated endpoint (CDN,
# etc.), keep RUNTIME_API_ORIGIN unset and use STREAM_ORIGIN instead.
# RUNTIME_API_ORIGIN=http://webapp:3000

# Webapp - memory management
# - This sets the maximum memory allocation for Node.js heap in MiB (e.g. "4096" for 4GB)
Expand Down
1 change: 1 addition & 0 deletions hosting/docker/webapp/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ services:
APP_ORIGIN: ${APP_ORIGIN:-http://localhost:8030}
LOGIN_ORIGIN: ${LOGIN_ORIGIN:-http://localhost:8030}
API_ORIGIN: ${API_ORIGIN:-http://localhost:8030}
RUNTIME_API_ORIGIN: ${RUNTIME_API_ORIGIN:-}
Comment thread
devin-ai-integration[bot] marked this conversation as resolved.
ELECTRIC_ORIGIN: http://electric:3000
DATABASE_URL: ${DATABASE_URL:-postgresql://postgres:postgres@postgres:5432/main?schema=public&sslmode=disable}
DIRECT_URL: ${DIRECT_URL:-postgresql://postgres:postgres@postgres:5432/main?schema=public&sslmode=disable}
Expand Down
4 changes: 4 additions & 0 deletions hosting/k8s/helm/templates/webapp.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,10 @@ spec:
value: {{ .Values.webapp.loginOrigin | quote }}
- name: API_ORIGIN
value: {{ .Values.webapp.apiOrigin | quote }}
{{- with .Values.webapp.runtimeApiOrigin }}
- name: RUNTIME_API_ORIGIN
value: {{ . | quote }}
{{- end }}
- name: ELECTRIC_ORIGIN
value: {{ include "trigger-v4.electric.url" . | quote }}
{{- if include "trigger-v4.postgres.useSecretUrl" . }}
Expand Down
6 changes: 6 additions & 0 deletions hosting/k8s/helm/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ webapp:
appOrigin: "http://localhost:3040"
loginOrigin: "http://localhost:3040"
apiOrigin: "http://localhost:3040"
# Origin advertised to runner pods as TRIGGER_API_URL.
# When unset (default), runners use apiOrigin/appOrigin. Set this to an
# in-cluster service URL to keep runner->webapp traffic inside the cluster,
# bypassing gateways/proxies (e.g. Envoy with tracing enabled) that rewrite
# the W3C `traceparent` header on egress and break the parent->child run link.
runtimeApiOrigin: ""

replicaCount: 1

Expand Down