Skip to content

feat(webapp,cli): let self-hosted instances require deploy base images - #5005

Merged
nicktrn merged 9 commits into
triggerdotdev:mainfrom
brentshulman-silkline:feat/instance-deploy-base-images
Oct 10, 2026
Merged

nicktrn merged 9 commits into
triggerdotdev:mainfrom
brentshulman-silkline:feat/instance-deploy-base-images

Conversation

@brentshulman-silkline

@brentshulman-silkline brentshulman-silkline commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Closes #5004

Lets a self-hosted operator require custom base images for every deploy to their instance, such as FIPS-validated or hardened Node images. Cloud never sets the variables, so nothing changes there.

DEPLOY_BASE_IMAGES="node-26=registry.example.com/node-fips:26@sha256:<digest>"
DEPLOY_BUILD_BASE_IMAGES="node-26=registry.example.com/node:26-dev@sha256:<digest>"  # optional
  • Webapp validates both variables at startup (known runtime, digest-pinned, no duplicates) and fails loud on bad values.
  • Deployments return the images for their runtime as baseImages; the CLI rewrites the Containerfile with them. A configured build image is also used when a project has image.instructions.
  • Deploys from CLIs that can't apply them, and --native-build, --local-bundle and --from-bundle deploys, are rejected with a clear error.
  • Docs: env rows plus a "Custom base images" section in the self-hosting overview.

Testing

apps/webapp/test/deployBaseImages.test.ts and packages/cli-v3/src/deploy/buildImage.test.ts cover the parsing, rejection and Containerfile cases. Typecheck, format and lint are clean.

Adds DEPLOY_BASE_IMAGES / DEPLOY_BUILD_BASE_IMAGES (runtime=image csv) to the
webapp. The deployment initialize response carries the images for the deploy's
runtime, and the CLI rewrites the Containerfile to build on them.
@changeset-bot

changeset-bot Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: fdf367a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 28 packages
Name Type
@trigger.dev/core Patch
trigger.dev Patch
@trigger.dev/build Patch
@trigger.dev/python Patch
@trigger.dev/redis-worker Patch
@trigger.dev/schema-to-json Patch
@trigger.dev/sdk Patch
@internal/clickhouse Patch
@internal/llm-model-catalog Patch
@internal/metrics-pipeline Patch
@trigger.dev/rbac Patch
@internal/redis Patch
@internal/replication Patch
@internal/run-engine Patch
@internal/run-store Patch
@internal/schedule-engine Patch
@internal/tracing Patch
@internal/webhook-engine Patch
@internal/webhook-sources Patch
@internal/dashboard-agent Patch
@internal/cache Patch
@trigger.dev/react-hooks Patch
@trigger.dev/rsc Patch
@trigger.dev/billing Patch
@trigger.dev/database Patch
@trigger.dev/otlp-importer Patch
@trigger.dev/sso Patch
@internal/testcontainers Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai

coderabbitai Bot commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: bf7654f9-b830-4f58-b187-71cc367582ef

📥 Commits

Reviewing files that changed from the base of the PR and between 0549f55 and fdf367a.


📒 Files selected for processing (3)
  • apps/webapp/app/env.server.ts
  • docs/self-hosting/env/webapp.mdx
  • packages/core/src/v3/schemas/api.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📜 Recent review details
⏰ Context from checks skipped due to timeout. (50)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (22, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (24, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (14, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (9, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (17, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (7, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (16, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (19, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (13, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (23, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (20, 24)
  • GitHub Check: sdk-compat / Node.js 20.20 (warp-ubuntu-latest-x64-4x)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (10, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (8, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (18, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (6, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (11, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (21, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (12, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (4, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (2, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (15, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (5, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (1, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (3, 24)
  • GitHub Check: sdk-compat / Node.js 22.23 (warp-ubuntu-latest-x64-4x)
  • GitHub Check: packages / 🧪 Unit Tests: Packages (2, 3)
  • GitHub Check: e2e / 🧪 CLI v3 tests (warp-windows-latest-x64-8x - pnpm)
  • GitHub Check: sdk-compat / Node.js 24.18 (warp-ubuntu-latest-x64-4x)
  • GitHub Check: e2e / 🧪 CLI v3 tests (warp-ubuntu-latest-x64-4x - pnpm)
  • GitHub Check: sdk-compat / Deno Runtime
  • GitHub Check: e2e / 🧪 CLI v3 tests (warp-windows-latest-x64-8x - npm)
  • GitHub Check: sdk-compat / Node.js 26.4 (warp-ubuntu-latest-x64-4x)
  • GitHub Check: packages / 🧪 Unit Tests: Packages (3, 3)
  • GitHub Check: typecheck / typecheck
  • GitHub Check: packages / 🧪 Unit Tests: Packages (1, 3)
  • GitHub Check: e2e / 🧪 CLI v3 tests (warp-ubuntu-latest-x64-4x - npm)
  • GitHub Check: internal / 🧪 Unit Tests: Internal (1)
  • GitHub Check: sdk-compat / Bun Runtime
  • GitHub Check: sdk-compat / Cloudflare Workers
  • GitHub Check: internal / 🧪 Unit Tests: Internal (2)
  • GitHub Check: runops-guard / runops-guard
  • GitHub Check: e2e-webapp / 🧪 E2E Tests: Webapp (2, 2)
  • GitHub Check: fk-cascade-guard / fk-cascade-guard
  • GitHub Check: obsmap / 🧪 Unit Tests: Observability Map
  • GitHub Check: e2e-webapp / 🧪 E2E Tests: Webapp (1, 2)
  • GitHub Check: code-quality / code-quality
  • GitHub Check: 🛡️ E2E Auth Tests (full)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Analyze (actions)

🧰 Additional context used
📚 Code guidelines (1)
.cursor/rules/webapp.mdc — auto-discovered

📓 Path-based instructions (1)
Source excerpt: In the webapp, all environment variables are accessed through the `env` export of [env.server.ts](mdc:apps/webapp/app/env.server.ts), instead of directly accessing `process.env`.

📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)

Files:

  • apps/webapp/app/env.server.ts


Walkthrough

The webapp parses per-runtime deploy and build image settings and returns matching images in deployment responses. Deployment initialization rejects native builds and clients that do not declare support when custom images are required. The CLI applies returned images when generating Containerfiles for standard deployments and rejects bundle deployments that require custom images. Containerfile generation uses runtime defaults when image fields are not configured. The changes also add API schemas, tests, self-hosting documentation, and release notes.

Priority: ➖ Normal

Merge Risk: ⚪ Minimal · up to fdf36

Unset settings remain safe, and deployments without a configured runtime image continue using the CLI defaults. No actionable merge risk was identified in the reviewed changes.

Security Architecture Review

Security architecture risk: 🟡 Moderate · up to 5d3fb

Configured image requirements are not enforced consistently across deployment paths. The normal deployment path honors the runtime base image, but bundle builds and existing-deployment attachment can omit it, and project instructions can override the selected build-stage image. Exposure is limited to authenticated deployers on configured instances; existing environment authorization remains intact.

Retained concerns

  • High · security · inferred: The instance-required runtime image is only enforced by the fresh main CLI deployment path. From-bundle builds use their existing Containerfile without applying baseImages, while explicit existing-deployment attachment obtains no image overrides. Finalization verifies deployment ownership and state, not approved base ancestry. An authenticated deployer can therefore deploy an image outside the configured requirement, including for a runtime that has a mapping.
  • Medium · security · observed: Even in the main deployment path, any nonempty project image.instructions selects FROM base plus an apt-installed toolchain instead of the operator-selected buildBase. The runtime base remains selected, but the approved build-stage image is not required. This branch predates the PR for default images; the new security-relevant mismatch is its precedence over an instance-configured build-image requirement.
Security review details

Security Blast Radius

  • inferred — The policy applies instance-wide by runtime, so inconsistent enforcement can affect multiple projects and environments using configured runtimes. Exercising the identified bypass requires deployment authority in the target environment and control of the build path or bundle; it does not demonstrate additional cross-environment authority.

Security Findings and Attack Paths

  • inferred — An authenticated deployer can supply a bundle Containerfile using another runtime base, initialize a local deployment, and build and finalize without applying the returned requirement. The admission path checks environment ownership, worker presence, deployment state, and digest syntax, but not the configured base-image ancestry.
  • observed — A project-controlled nonempty instructions list bypasses buildBase selection within Containerfile generation. The alternate stage still derives from the selected runtime base, limiting this mismatch to the separately configured build-stage requirement.

Trust Boundaries and Controls

  • observed — Trusted operator configuration is conveyed to a deployer-controlled build host through an optional response field. The main consumer honors its precedence, but the server's finalization boundary does not require evidence that the resulting artifact used those images. Existing environment-scoped authorization remains in place.

Resilience and Maintainability Implications

  • observed — Image policy is not included in the inspected deployment creation record. Legacy POST attachment re-resolves current configuration, whereas explicit CLI attachment retrieves the deployment through GET, whose response omits baseImages. These recovery paths therefore do not share a durable image-policy handoff.

Hardening Proposals

  • proposed — If these settings are mandatory security policy, consider server-owned image requirements tied to deployment identity and verified artifact provenance before admission. Apply the contract consistently to fresh builds, bundles, and attachment, and define whether project instructions are permitted to replace a required build-stage image. Alternatively, explicitly expose the feature as advisory image selection rather than enforcement.

Pre-merge checks | Passed 4 | Failed 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 12 functions across 12 files. (1 skipped:… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main change: allowing self-hosted instances to require deploy base images.
Description check Passed The description identifies the linked issue, explains the implementation and scope, documents testing, and summarizes the change. It omits the checklist and screenshots sections, but the required tech…
Linked Issues check Passed [#5004] The webapp validates optional runtime-specific, digest-pinned image settings at startup. The deployment responses include resolved baseImages, and configured runtimes override the published …
Out of Scope Changes check Passed The changes stay within [#5004]. They add instance environment parsing, deployment response fields, CLI image application and rejection handling, schemas, focused tests, release metadata, and self-hos…

Full details: Docstring Coverage

Explanation

Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 12 functions across 12 files. (1 skipped: 1 unsupported.)


  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
🧪 Generate unit tests (beta)
  • Create a new PR

🛠️ Fix failing CI checks 💡
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

coderabbitai[bot]

This comment was marked as resolved.

Validate DEPLOY_BASE_IMAGES and DEPLOY_BUILD_BASE_IMAGES when the webapp starts: entries must name a known runtime and a digest-pinned image, with no duplicate runtimes. Invalid values fail startup instead of silently falling back to the published images.

Honor the build-stage image when build extensions add image instructions: the build stage is created from the configured build image and the instructions are replayed on it, instead of being derived from the base with a toolchain install.

Apply the server's base images on --from-bundle deploys by regenerating the bundle's Containerfile, and print the images in the deploy output.

Docs: split the Node and Bun base image requirements, describe the validation rules and the paths the setting applies to.
Reject initialize-deployment requests from CLIs that cannot apply the instance's base images, so the setting is enforced rather than advisory. The CLI declares support on the paths that can honour it, and fails with a clear error on --native-build and --local-bundle, which cannot.

Return the base images on the get-deployment response as well, so deploys that attach to an existing deployment build on them too.

Validate image refs with one shared schema in core on both the server and the CLI: a single token pinned by digest. Reject the runtime alias node in favour of the concrete runtime keys, and report every invalid env entry in one error at startup.

Build the custom build stage with the same customization block as the base stage, so instructions and package installs run in the same order.
…e set

Native builds and local bundles cannot apply the instance's base images and never declared support, so the server was rejecting them with the message meant for outdated CLIs. Reject them with their own message on the server and drop the CLI-side checks that could never run.

Docs: describe what the build stage uses without a build image entry, note that --from-bundle rewrites the Containerfile inside the bundle directory, and shorten the env table rows.
@nicktrn
nicktrn marked this pull request as ready for review October 7, 2026 13:56
devin-ai-integration[bot]

This comment was marked as resolved.

@nicktrn
nicktrn added this pull request to the merge queue Oct 10, 2026
Merged via the queue into triggerdotdev:main with commit 93465d8 Oct 10, 2026
66 of 67 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: let self-hosted instances require custom deploy base images (FIPS / hardened)

2 participants