fix(registry): use pnpm deploy for monorepo-aware Dockerfile#110
Merged
Conversation
#100 switched the registry's `@nimblebrain/mpak-schemas` dep from `^0.2.0` (published) to `workspace:*` so schemas changes are immediately consumable without a publish-bump dance — matching the convention every other package in the workspace already uses (`cli`, `sdk-typescript`, `web`). The Dockerfile, however, was written single-package and only copied `apps/registry/`, never any workspace dep source. Build then errored across every file importing schemas: src/routes/auth.ts(3,53): error TS2307: Cannot find module '@nimblebrain/mpak-schemas' or its corresponding type declarations. ... (15 more) ## The fix: `pnpm deploy` `pnpm deploy --filter=<pkg> --prod <out>` is pnpm's purpose-built solution for "containerize a workspace package": it walks the full dependency closure (workspace + npm), builds a flattened deployable directory, and resolves all `workspace:*` links by bundling each workspace package's compiled `dist/` inline. Single COPY in the runtime stage; future workspace deps require no Dockerfile change. Builder stage: - `COPY . .` brings the whole monorepo in (kept lean by .dockerignore). - `pnpm install --frozen-lockfile` resolves all workspace links. - `pnpm --filter ... exec prisma generate` writes the generated client into the pnpm hoisted store. - `pnpm --filter @nimblebrain/mpak-registry... build` builds the registry AND every transitive workspace dep (`...` filter syntax). - `pnpm deploy --filter=@nimblebrain/mpak-registry --prod /deploy` flattens registry + prod deps + workspace closures into /deploy. Production stage: - One `COPY --from=builder /deploy ./` brings everything the runtime needs — registry dist, schemas dist, every npm prod dep. - The Prisma generated client is the one exception: its sibling `.prisma/` folder lives in the pnpm hoisted store and isn't carried by `pnpm deploy`. Two explicit COPY lines preserved from the prior Dockerfile handle that special case. `.dockerignore` (new) keeps the build context small — excludes every package's `node_modules`, `dist`, `.astro`, `.turbo`, `.git`, `.env*`, test outputs, editor state. ## Verified locally - `docker build -f apps/registry/Dockerfile -t mpak-registry:test .` → succeeds end-to-end (was failing on the original tsc step). - `docker run mpak-registry:test` → boots: Prisma initializes, every module loads, Fastify listens on :3200. - `node -e "import('@nimblebrain/mpak-schemas').then(...)"` inside the image → schemas resolves, `ServerDetailSchema` is an object. ## Why not the simpler `COPY packages/schemas/...` patch Considered first, rejected because it's per-dep — every future workspace dep added to the registry would need another COPY pair in both stages. `pnpm deploy` is what pnpm's monorepo-Docker docs recommend and scales to N workspace deps with no Dockerfile churn.
3eaa208 to
4d615d6
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Deploy-blocking —
make deploy-all ENV=stagingagainst current main fails the docker build on the registry tsc step:Root cause
#100 switched the registry's
@nimblebrain/mpak-schemasdep from^0.2.0(published) toworkspace:*. That's the right call — it matches the convention every other package in the workspace already uses (cli,sdk-typescript,web), and removes the publish-bump dance every schemas change otherwise required. The^0.2.0pin was actually the band-aid: it dodged the Dockerfile problem by pretending the registry wasn't in a monorepo.The Dockerfile, however, was written single-package and only copied
apps/registry/, never any workspace dep source.The fix:
pnpm deploypnpm deploy --filter=<pkg> --prod <out>is pnpm's purpose-built solution for "containerize a workspace package": it walks the full dependency closure (workspace + npm), builds a flattened deployable directory, and resolves allworkspace:*links by inlining each workspace package's compileddist/. One COPY in the runtime stage; future workspace deps require no Dockerfile change.Considered the simpler patch first (
COPY packages/schemas/...thenpnpm --filter ... buildper-package) but rejected it as per-dep band-aid — the next workspace dep added to the registry would need another COPY pair in both stages.Builder stage
COPY . .brings the whole monorepo in (kept lean by.dockerignore)pnpm install --frozen-lockfileresolves all workspace linkspnpm --filter @nimblebrain/mpak-registry exec prisma generatewrites the generated clientpnpm --filter @nimblebrain/mpak-registry... buildbuilds registry + every transitive workspace dep (...filter syntax)pnpm deploy --filter=@nimblebrain/mpak-registry --prod /deployflattens everything into/deployProduction stage
COPY --from=builder /deploy ./brings everything the runtime needs.prisma/folder (lives in the pnpm hoisted store, not carried bypnpm deploy— the one true special case).dockerignore(new)Keeps the build context small — excludes every package's
node_modules,dist,.astro,.turbo,.git,.env*, test outputs, editor state.Test plan
docker build -f apps/registry/Dockerfile -t mpak-registry:test .— succeeds end-to-end (was failing on tsc)docker run mpak-registry:test— boots fully: Prisma initializes, every module loads, Fastify listens on:3200node -e "import('@nimblebrain/mpak-schemas').then(m => console.log(typeof m.ServerDetailSchema))"→objectmake deploy-all ENV=stagingfromdeployments/mpaksucceeds end-to-endFast-merge candidate.