Skip to content

fix(docker): ship the realtime and migrations images with runtime dependencies only - #9983

Merged
waleedlatif1 merged 1 commit into
stagingfrom
fix/production-only-images
Nov 13, 2026
Merged

waleedlatif1 merged 1 commit into
stagingfrom
fix/production-only-images

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

  • Bun's --omit=dev skips the root's devDependencies but still installs every workspace member, each member's devDependencies, and any optional peers the lockfile can satisfy. So the realtime and migrations images shipped drizzle-kit (with its bundled esbuild binaries), vitest, vite and tsx. The esbuild Go binaries accounted for almost every HIGH/CRITICAL scanner finding in both images.
  • New scripts/prune-production-workspace.ts narrows a turbo prune --docker output to the workspace members the target actually reaches through dependencies, optionalDependencies, or a tsconfig.json extends (Bun reads tsconfig at runtime). It drops every other member, such as @sim/testing, and strips devDependencies from the root and the kept members. The root's devDependencies have to go too: otherwise Bun links the locked vitest to satisfy better-auth's optional peer.
  • The realtime image uses that narrowed workspace.
  • The migrations image now uses turbo prune like realtime, which replaces the hand-maintained manifest list.
    • Its final stage (the default) runs db:migrate with runtime dependencies only.
    • A new dev stage keeps drizzle-kit for the dev environment's db:push --force. image-dev builds that stage through a new target input on the image action.
    • Staging, production, GHCR, docker-compose and Helm all build the default stage.
  • The narrowed installs drop --frozen-lockfile, as the migrations image already did. Bun keeps every locked resolution, and full-repository CI owns frozen-lockfile validation. I checked every installed third-party package against the repo lockfile: realtime 118/118 and migrations 6/6 are at a locked version.

Type of Change

  • Bug fix

Testing

  • Built all three images locally (arm64):

    Image Before After node_modules
    realtime 1.21 GB 562 MB 592 MB → 128 MB
    migrations 1.07 GB 428 MB 490 MB → 21 MB
    migrations dev stage — 1.07 GB still carries drizzle-kit, as dev needs
  • Neither production image contains drizzle-kit, @esbuild-kit, esbuild, tsx, vite, vitest, typescript or @sim/testing.

  • trivy HIGH/CRITICAL findings:

    • realtime: 4 critical + 56 high → 1 critical + 2 high. The remainder is the existing better-auth advisories, which are a runtime dependency and out of scope here.
    • migrations: 3 critical + 69 high → none.
  • Ran bun run db:migrate from the new migrations image against a scratch pgvector pg17 database: it completes.

  • Booted the new realtime image against scratch Postgres and Redis: /health returns 200 and the socket.io polling handshake succeeds.

  • biome on the new script.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing (new tests pass the test-audit authoring gate)
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

…endencies only

Bun's --omit=dev skips the root's devDependencies but still installs every
workspace member, each member's devDependencies, and the optional peers the
lockfile can satisfy. Both images therefore carried drizzle-kit (with its
bundled esbuild binaries), vitest, vite and tsx, and the esbuild Go binaries
account for nearly all of their HIGH/CRITICAL scanner findings.

scripts/prune-production-workspace.ts narrows a turbo prune to the members the
target reaches through dependencies, optionalDependencies or a tsconfig extends,
and strips devDependencies from the root and the kept members. The migrations
image gains a dev stage that keeps drizzle-kit for the dev environment's
db:push; its final stage, which every other environment builds, runs db:migrate
with runtime dependencies only.
@vercel

vercel Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
docs Ready Ready Preview Nov 13, 2026 4:49am UTC

Request Review

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues found across 5 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Turn on auto-fix | Re-trigger cubic

@greptile-apps

greptile-apps Bot commented Nov 13, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no actionable issues were found.

Summary

Removes development dependencies from the realtime and default migrations images.

  • Realtime and migration images keep only the workspace packages they run.
  • CI can select the dev migration image stage.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Repository] --> B[turbo prune]
  B --> C[Pruned workspace]
  C --> D[Production workspace script]
  D --> E[Runtime dependency install]
  E --> F[Realtime or migrations runner]
  C --> G[Full dependency install]
  G --> H[Migrations dev stage]
  I[Dev CI target] --> H
Loading

Reviews (1) · Last reviewed commit: "fix(docker): ship the realtime and migra..." · Reviewed by Greptile

This branch was successfully deployed

1 active deployment
Preview — e387d598 Deployed Nov 13, 2026 by vercel[bot]
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.

1 participant