# ─── Web app Dockerfile ─────────────────────────────────────────────────────── # Alpine — small final image; no native addons needed for web. FROM node:22-alpine AS base RUN apk add --no-cache libc6-compat WORKDIR /app # ─── Dependencies ───────────────────────────────────────────────────────────── FROM base AS deps COPY package.json package-lock.json* tsconfig.base.json ./ COPY apps/web/package.json ./apps/web/ COPY worker/package.json ./worker/ COPY shared/package.json ./shared/ # NODE_ENV must NOT be production here — devDependencies (tsc, next, etc.) are required RUN npm install --workspace=apps/web --workspace=worker --workspace=shared # ─── Shared build ───────────────────────────────────────────────────────────── FROM deps AS shared-build COPY shared/ ./shared/ RUN npm run build --workspace=shared # ─── Next.js build ──────────────────────────────────────────────────────────── FROM shared-build AS web-build COPY apps/web/ ./apps/web/ RUN npm run build --workspace=apps/web # ─── Web runtime ────────────────────────────────────────────────────────────── FROM node:22-alpine AS web RUN apk add --no-cache libc6-compat RUN addgroup --system --gid 1001 nodejs && adduser --system --uid 1001 nextjs WORKDIR /app ENV NODE_ENV=production COPY --from=deps /app/node_modules ./node_modules COPY --from=web-build /app/apps/web/.next ./apps/web/.next COPY --from=web-build /app/apps/web/public ./apps/web/public COPY --from=shared-build /app/shared/dist ./shared/dist COPY shared/package.json ./shared/ COPY apps/web/package.json ./apps/web/ USER nextjs WORKDIR /app/apps/web EXPOSE 3000 CMD ["/app/node_modules/.bin/next", "start"]