From 3e581b682122ceeb5cee56ac8fa97a7129ad3792 Mon Sep 17 00:00:00 2001 From: Nicky Leach Date: Sat, 5 Sep 2026 09:19:59 -0700 Subject: [PATCH] docs(docker): explain why the prune stage deletes then reinstalls A reviewer flagged the delete-then-reinstall as surprising on its own. Spell out why it's structurally necessary rather than incidental: `build` needs the full devDependency toolchain to compile, and pnpm has no narrower primitive that scopes a prod-only prune to one workspace member's graph (`pnpm prune --prod` only prunes the root importer and takes no --filter). Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01RD53WaVFqm8pbntKZ5seWy --- Dockerfile | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Dockerfile b/Dockerfile index 48dbfe35b0..4274841095 100644 --- a/Dockerfile +++ b/Dockerfile @@ -116,6 +116,17 @@ RUN rm -rf packages/paperclip-runner/runner/target # `server...` filter (server plus everything it actually depends on, # transitively) is safe and drops the unused weight. # +# This deletes node_modules and reinstalls rather than installing narrow +# from the start, because nothing earlier in the pipeline can afford to +# skip the full install: `build` above needs every devDependency present +# (typescript, vite, cargo's crates, ...) to actually compile the ui, +# plugin-sdk, and server. Only once that's done do we know it's safe to +# drop them. `pnpm prune --prod` looked like the narrower tool for this, +# but it only prunes the *root* workspace importer's devDependencies, not +# each member's independently, and takes no --filter -- so it can't scope +# to just server's own graph. A filtered `install --prod` is the only +# primitive that does, and it requires a clean node_modules first. +# # tsx is deliberately NOT pruned: server/package.json lists it as a # production dependency (not dev) because the ENTRYPOINT below imports it # directly (`--import ./server/node_modules/tsx/...`) to transpile the