fix(01-01): build Docker image from repo-root pnpm workspace context
The walking-skeleton Dockerfile built from a ./apps/api context and could not
work in a pnpm workspace: the lockfile lives at the repo root, pnpm 11 refused
esbuild's build script without the root pnpm-workspace.yaml, the dev stage never
compiled src->dist, and the production stage had invalid COPY syntax referencing
a path outside its context.
Switch to the correct monorepo pattern: build from the repo-root context, copy
the workspace manifest + lockfile + both package.jsons, and install with
--frozen-lockfile --filter @familysync/api... Reorder stages so production is
default; dev reuses builder output. Fix the dev volume mount path.
Surfaced while clearing the Task 3 checkpoint (stack bring-up): drizzle-kit push
applied the 4 tables and /health returned {ok:true,db:up} end-to-end.
This commit is contained in:
+26
-22
@@ -1,29 +1,33 @@
|
||||
# Built from the REPO ROOT context (see docker-compose.yml: build.context: .)
|
||||
# so the pnpm workspace manifest + lockfile are available for a deterministic,
|
||||
# workspace-aware install. apps/api is one package in the pnpm workspace.
|
||||
FROM node:22-alpine AS base
|
||||
WORKDIR /app
|
||||
RUN corepack enable pnpm
|
||||
|
||||
FROM base AS deps
|
||||
COPY package.json pnpm-lock.yaml* ./
|
||||
RUN pnpm install --frozen-lockfile --prod
|
||||
|
||||
# Install layer: copy only manifests + lockfile first for cache efficiency.
|
||||
# Both workspace package.json files are needed so --frozen-lockfile can validate
|
||||
# every importer in pnpm-lock.yaml. pnpm-workspace.yaml carries allowBuilds.esbuild.
|
||||
FROM base AS builder
|
||||
COPY package.json pnpm-lock.yaml* ./
|
||||
RUN pnpm install --frozen-lockfile
|
||||
COPY tsconfig.json ./
|
||||
COPY src/ ./src/
|
||||
RUN pnpm build
|
||||
|
||||
FROM base AS production
|
||||
WORKDIR /app
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
COPY --from=builder /app/dist ./dist
|
||||
# PWA static assets served from ./public (built separately)
|
||||
COPY apps/pwa/dist/ ./public/ 2>/dev/null || true
|
||||
CMD ["node", "dist/index.js"]
|
||||
COPY pnpm-workspace.yaml pnpm-lock.yaml package.json ./
|
||||
COPY apps/api/package.json ./apps/api/
|
||||
COPY apps/pwa/package.json ./apps/pwa/
|
||||
RUN pnpm install --frozen-lockfile --filter @familysync/api...
|
||||
COPY apps/api ./apps/api
|
||||
RUN pnpm --filter @familysync/api build
|
||||
|
||||
FROM base AS dev
|
||||
WORKDIR /app
|
||||
COPY package.json pnpm-lock.yaml* ./
|
||||
RUN pnpm install --frozen-lockfile
|
||||
COPY tsconfig.json ./
|
||||
CMD ["pnpm", "dev"]
|
||||
WORKDIR /app/apps/api
|
||||
COPY --from=builder /app /app
|
||||
CMD ["node", "--watch", "dist/index.js"]
|
||||
|
||||
FROM base AS production
|
||||
COPY pnpm-workspace.yaml pnpm-lock.yaml package.json ./
|
||||
COPY apps/api/package.json ./apps/api/
|
||||
COPY apps/pwa/package.json ./apps/pwa/
|
||||
RUN pnpm install --frozen-lockfile --prod --filter @familysync/api...
|
||||
COPY --from=builder /app/apps/api/dist ./apps/api/dist
|
||||
WORKDIR /app/apps/api
|
||||
# PWA static assets (apps/pwa) are built and served separately; /health works
|
||||
# without them and the catch-all static route 404s gracefully.
|
||||
CMD ["node", "dist/index.js"]
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
services:
|
||||
api:
|
||||
build:
|
||||
context: ./apps/api
|
||||
context: .
|
||||
dockerfile: apps/api/Dockerfile
|
||||
target: dev
|
||||
volumes:
|
||||
- ./apps/api/src:/app/src
|
||||
- ./apps/api/src:/app/apps/api/src
|
||||
environment:
|
||||
NODE_ENV: development
|
||||
|
||||
|
||||
+4
-1
@@ -1,6 +1,9 @@
|
||||
services:
|
||||
api:
|
||||
build: ./apps/api
|
||||
build:
|
||||
context: .
|
||||
dockerfile: apps/api/Dockerfile
|
||||
target: production
|
||||
environment:
|
||||
DB_HOST: mariadb
|
||||
DB_PORT: 3306
|
||||
|
||||
Reference in New Issue
Block a user