# Dockerfile.labd -- multi-stage build for the labd master daemon # Runs the Fastify API server with Prisma/CockroachDB backend. # ── Stage 1: Build ─────────────────────────────────────────────── FROM node:22-alpine AS builder RUN corepack enable && corepack prepare pnpm@9.15.0 --activate WORKDIR /app # Copy workspace config and package manifests first (layer cache) COPY pnpm-workspace.yaml pnpm-lock.yaml package.json tsconfig.base.json tsconfig.json ./ COPY src/shared/package.json src/shared/tsconfig.json src/shared/ COPY src/core/package.json src/core/tsconfig.json src/core/ COPY src/labd/package.json src/labd/tsconfig.json src/labd/ # Install all dependencies (dev included -- needed for build) RUN pnpm install --frozen-lockfile # Copy Prisma schema and generate client COPY src/labd/prisma/ src/labd/prisma/ RUN pnpm --filter @lab/labd exec prisma generate # Copy source code COPY src/shared/src/ src/shared/src/ COPY src/core/src/ src/core/src/ COPY src/labd/src/ src/labd/src/ # Build TypeScript (shared + core before labd via project references) RUN pnpm --filter @lab/shared build \ && pnpm --filter @lab/core build \ && pnpm --filter @lab/labd build # Hoist the generated Prisma client so stage 2 can COPY it from a stable path RUN mkdir -p /app/_prisma && \ cp -r $(find /app/node_modules/.pnpm -path '*/.prisma/client' -type d | head -1) /app/_prisma/client # ── Stage 2: Production runtime ───────────────────────────────── FROM node:22-alpine RUN corepack enable && corepack prepare pnpm@9.15.0 --activate WORKDIR /app # Copy workspace config and package manifests COPY pnpm-workspace.yaml pnpm-lock.yaml package.json ./ COPY src/shared/package.json src/shared/ COPY src/core/package.json src/core/ COPY src/labd/package.json src/labd/ # Install production dependencies only RUN pnpm install --frozen-lockfile --prod 2>/dev/null || pnpm install --prod # Copy built output from builder COPY --from=builder /app/src/shared/dist/ src/shared/dist/ COPY --from=builder /app/src/core/dist/ src/core/dist/ COPY --from=builder /app/src/labd/dist/ src/labd/dist/ # Copy Prisma schema + generated client into pnpm store location # Prisma expects .prisma/client as a sibling of @prisma/ in the same node_modules COPY --from=builder /app/src/labd/prisma/ src/labd/prisma/ COPY --from=builder /app/_prisma/client/ /tmp/_prisma_client/ RUN PRISMA_CLIENT_DIR=$(find /app/node_modules/.pnpm -path '*/@prisma/client' -type d | head -1) && \ NM_DIR="$(dirname "$(dirname "$PRISMA_CLIENT_DIR")")" && \ mkdir -p "$NM_DIR/.prisma/client" && \ cp -r /tmp/_prisma_client/* "$NM_DIR/.prisma/client/" && \ echo "Installed Prisma generated client at: $NM_DIR/.prisma/client/" && \ rm -rf /tmp/_prisma_client ENV NODE_ENV=production ENV DATABASE_URL=postgresql://root@cockroachdb:26257/labctl?sslmode=disable ENV LABD_PORT=3100 ENV LABD_HOST=0.0.0.0 EXPOSE 3100 USER node ENTRYPOINT ["node", "src/labd/dist/main.js"]