# ─── Stage 1: Prune Workspace ───────────────────────────── FROM node:20-alpine AS pruner RUN apk add --no-cache libc6-compat WORKDIR /app RUN npm install -g turbo@2.8.12 COPY . . RUN turbo prune --scope=@micprotocol/web --docker # ─── Stage 2: Install Dependencies ──────────────────────── FROM node:20-alpine AS deps WORKDIR /app # Enable corepack for pnpm RUN corepack enable && corepack prepare pnpm@10.30.3 --activate # Copy pruned workspace metadata files COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./ COPY --from=pruner /app/out/json/ . # Install dependencies (development and production) RUN pnpm install --frozen-lockfile # ─── Stage 3: Build Application ─────────────────────────── FROM node:20-alpine AS builder WORKDIR /app # Enable corepack for pnpm RUN corepack enable && corepack prepare pnpm@10.30.3 --activate # Copy installed dependencies and full pruned workspace source code COPY --from=deps /app /app COPY --from=pruner /app/out/full/ . # Generate Prisma client for @micprotocol/api since Next.js type-checks API source files directly RUN pnpm db:generate # Build internal workspace dependencies first RUN pnpm --filter @micprotocol/shared-types build RUN pnpm --filter @micprotocol/ui build # Build the web application directly (bypassing turbo task runner to avoid compiling NestJS API backend) RUN DOCKER_BUILD=true pnpm --filter @micprotocol/web build # Prune devDependencies to keep only production dependencies RUN CI=true pnpm install --prod --frozen-lockfile # ─── Stage 4: Production Runner ─────────────────────────── FROM node:20-alpine AS runner WORKDIR /app ENV NODE_ENV=production ENV PORT=3000 ENV HOSTNAME="0.0.0.0" # Create non-root user RUN addgroup --system --gid 1001 nodejs RUN adduser --system --uid 1001 nextjs # Copy standalone build outputs COPY --from=builder /app/apps/web/public ./apps/web/public COPY --from=builder --chown=nextjs:nodejs /app/apps/web/.next/standalone ./ COPY --from=builder --chown=nextjs:nodejs /app/apps/web/.next/static ./apps/web/.next/static # Switch to non-root user USER nextjs EXPOSE 3000 # Start application using Next.js standalone server CMD ["node", "apps/web/server.js"]