Skip to content

Commit 169fada

Browse files
committed
fix(docker): preserve workspace dir structure in runtime for pnpm symlinks
pnpm places each workspace package's deps in its own node_modules/ (e.g. apps/template/backend/node_modules/dotenv) with symlinks into the root .pnpm virtual store. Flattening to /app/dist + /app/node_modules puts Node in the wrong directory, so it never walks down to the package-level node_modules and can't find runtime deps like dotenv. Fix: copy both the root node_modules (virtual store) AND the package's own node_modules into the runtime stage, then set WORKDIR to the package path so Node's module resolution walks the correct tree.
1 parent c4d5ca8 commit 169fada

File tree

2 files changed

+14
-12
lines changed

2 files changed

+14
-12
lines changed

apps/cas/backend/Dockerfile

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,13 @@ LABEL org.opencontainers.image.title="cas-backend" \
4848

4949
WORKDIR /app
5050

51-
# Copy node_modules directly from builder — the compiled better_sqlite3.node
52-
# binary is already present there from the pnpm rebuild step above.
53-
# (pnpm deploy performs a fresh install that skips build scripts, so the
54-
# binary is absent in a deploy dir — skip deploy entirely.)
51+
# Preserve the full workspace directory structure from the builder so that
52+
# pnpm's per-package node_modules symlinks (which point into the root
53+
# .pnpm virtual store) remain valid at runtime.
5554
COPY --from=builder /app/node_modules ./node_modules
56-
COPY --from=builder /app/apps/cas/backend/dist ./dist
57-
COPY --from=builder /app/apps/cas/backend/package.json ./
55+
COPY --from=builder /app/apps/cas/backend/node_modules ./apps/cas/backend/node_modules
56+
COPY --from=builder /app/apps/cas/backend/dist ./apps/cas/backend/dist
57+
COPY --from=builder /app/apps/cas/backend/package.json ./apps/cas/backend/package.json
5858

5959
RUN addgroup --system cas && adduser --system --ingroup cas cas
6060
USER cas
@@ -68,4 +68,5 @@ EXPOSE 3001
6868
HEALTHCHECK --interval=15s --timeout=5s --retries=3 \
6969
CMD node -e "require('http').get('http://localhost:3001/health', r => process.exit(r.statusCode === 200 ? 0 : 1)).on('error', () => process.exit(1))"
7070

71+
WORKDIR /app/apps/cas/backend
7172
CMD ["node", "dist/index.js"]

apps/template/backend/Dockerfile

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,13 @@ LABEL org.opencontainers.image.title="template-backend" \
3737

3838
WORKDIR /app
3939

40-
# Copy node_modules directly from builder — the compiled better_sqlite3.node
41-
# binary is already present there from the pnpm rebuild step above.
42-
# (pnpm deploy performs a fresh install that skips build scripts, so the
43-
# binary is absent in a deploy dir — skip deploy entirely.)
40+
# Preserve the full workspace directory structure from the builder so that
41+
# pnpm's per-package node_modules symlinks (which point into the root
42+
# .pnpm virtual store) remain valid at runtime.
4443
COPY --from=builder /app/node_modules ./node_modules
45-
COPY --from=builder /app/apps/template/backend/dist ./dist
46-
COPY --from=builder /app/apps/template/backend/package.json ./
44+
COPY --from=builder /app/apps/template/backend/node_modules ./apps/template/backend/node_modules
45+
COPY --from=builder /app/apps/template/backend/dist ./apps/template/backend/dist
46+
COPY --from=builder /app/apps/template/backend/package.json ./apps/template/backend/package.json
4747

4848
RUN addgroup --system template && adduser --system --ingroup template template
4949
USER template
@@ -57,4 +57,5 @@ EXPOSE 3002
5757
HEALTHCHECK --interval=15s --timeout=5s --retries=3 \
5858
CMD node -e "require('http').get('http://localhost:3002/health', r => process.exit(r.statusCode === 200 ? 0 : 1)).on('error', () => process.exit(1))"
5959

60+
WORKDIR /app/apps/template/backend
6061
CMD ["node", "dist/index.js"]

0 commit comments

Comments
 (0)