perf(docker): use turbo prune for app.Dockerfile (#4322)

* perf(docker): refactor app.Dockerfile to use turbo prune

Replaces manual workspace package.json copies with `turbo prune sim --docker`,
matching the canonical Vercel/Turborepo monorepo pattern (and the existing
realtime.Dockerfile).

- New `pruner` stage emits `out/json` (manifests + lockfile) and `out/full`
  (sources) for only the packages sim actually depends on.
- `deps` stage installs from the pruned manifest, so cache invalidates only
  when package.json/bun.lock change — not on source edits.
- Drops 24 lines of brittle manual COPYs (one per workspace package).
- Single full install in deps (no --omit=dev) so build-time devDeps like
  tailwindcss/postcss are available — replaces the earlier hotfix that did
  a second install in the builder stage.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* chore(docker): pin turbo to 2.9.6 in pruner stage

Match the version locked in package.json so pruner output is reproducible
across builds.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Waleed
2026-04-28 13:06:51 -07:00
committed by GitHub
co-authored by Claude Opus 4.7
parent 69dc2f04b8
commit dc20229954
+23 -58
View File
@@ -11,44 +11,35 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
&& curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
&& apt-get install -y nodejs
# ========================================
# Pruner Stage: Emit a minimal monorepo subset that sim depends on
# ========================================
FROM base AS pruner
WORKDIR /app
RUN bun install -g turbo@2.9.6
COPY . .
RUN turbo prune sim --docker
# ========================================
# Dependencies Stage: Install Dependencies
# ========================================
FROM base AS deps
WORKDIR /app
COPY package.json bun.lock turbo.json ./
RUN mkdir -p apps \
packages/audit \
packages/db \
packages/logger \
packages/realtime-protocol \
packages/security \
packages/testing \
packages/tsconfig \
packages/utils \
packages/workflow-authz \
packages/workflow-persistence \
packages/workflow-types
COPY apps/sim/package.json ./apps/sim/package.json
COPY packages/audit/package.json ./packages/audit/package.json
COPY packages/db/package.json ./packages/db/package.json
COPY packages/logger/package.json ./packages/logger/package.json
COPY packages/realtime-protocol/package.json ./packages/realtime-protocol/package.json
COPY packages/security/package.json ./packages/security/package.json
COPY packages/testing/package.json ./packages/testing/package.json
COPY packages/tsconfig/package.json ./packages/tsconfig/package.json
COPY packages/utils/package.json ./packages/utils/package.json
COPY packages/workflow-authz/package.json ./packages/workflow-authz/package.json
COPY packages/workflow-persistence/package.json ./packages/workflow-persistence/package.json
COPY packages/workflow-types/package.json ./packages/workflow-types/package.json
# Pruned manifests + lockfile from the pruner stage. This layer only invalidates
# when package.json/bun.lock content changes — not on source edits.
COPY --from=pruner /app/out/json/ ./
COPY --from=pruner /app/out/bun.lock ./bun.lock
# Install dependencies, then rebuild isolated-vm for Node.js
# Use --linker=hoisted for flat node_modules layout (required for Docker multi-stage builds)
# JOBS=4 caps node-gyp parallelism — higher values OOM isolated-vm (laverdet/isolated-vm#428)
# Install all dependencies (including devDependencies — tailwindcss/postcss are
# devDeps but required at build time). Then rebuild isolated-vm against Node.js.
# JOBS=4 caps node-gyp parallelism — higher values OOM isolated-vm (laverdet/isolated-vm#428).
RUN --mount=type=cache,id=bun-cache,target=/root/.bun/install/cache \
--mount=type=cache,id=npm-cache,target=/root/.npm \
HUSKY=0 bun install --omit=dev --ignore-scripts --linker=hoisted && \
HUSKY=0 bun install --ignore-scripts --linker=hoisted && \
cd node_modules/isolated-vm && JOBS=4 npx node-gyp rebuild --release
# ========================================
@@ -58,37 +49,11 @@ FROM base AS builder
ARG TARGETPLATFORM
WORKDIR /app
# Install turbo globally (cached for fast reinstall)
RUN --mount=type=cache,id=bun-cache,target=/root/.bun/install/cache \
bun install -g turbo
# Copy node_modules from deps stage (cached if dependencies don't change)
COPY --from=deps /app/node_modules ./node_modules
# Copy package configuration files (needed for build)
COPY package.json bun.lock turbo.json ./
COPY apps/sim/package.json ./apps/sim/package.json
COPY packages/audit/package.json ./packages/audit/package.json
COPY packages/db/package.json ./packages/db/package.json
COPY packages/logger/package.json ./packages/logger/package.json
COPY packages/realtime-protocol/package.json ./packages/realtime-protocol/package.json
COPY packages/security/package.json ./packages/security/package.json
COPY packages/testing/package.json ./packages/testing/package.json
COPY packages/tsconfig/package.json ./packages/tsconfig/package.json
COPY packages/utils/package.json ./packages/utils/package.json
COPY packages/workflow-authz/package.json ./packages/workflow-authz/package.json
COPY packages/workflow-persistence/package.json ./packages/workflow-persistence/package.json
COPY packages/workflow-types/package.json ./packages/workflow-types/package.json
# Copy workspace configuration files (needed for turbo)
COPY apps/sim/next.config.ts ./apps/sim/next.config.ts
COPY apps/sim/tsconfig.json ./apps/sim/tsconfig.json
COPY apps/sim/tailwind.config.ts ./apps/sim/tailwind.config.ts
COPY apps/sim/postcss.config.mjs ./apps/sim/postcss.config.mjs
# Copy source code (changes most frequently - placed last to maximize cache hits)
COPY apps/sim ./apps/sim
COPY packages ./packages
# Copy pruned source tree (apps/sim + workspace packages it depends on)
COPY --from=pruner /app/out/full/ ./
ENV NEXT_TELEMETRY_DISABLED=1 \
VERCEL_TELEMETRY_DISABLED=1 \
@@ -164,4 +129,4 @@ EXPOSE 3000
ENV PORT=3000 \
HOSTNAME="0.0.0.0"
CMD ["bun", "apps/sim/server.js"]
CMD ["bun", "apps/sim/server.js"]