# ===== DEPENDENCIES STAGE ===== FROM node:20-alpine AS deps WORKDIR /app # Install dependencies needed for native modules RUN apk add --no-cache libc6-compat openssl # Install ALL dependencies (including dev) for building COPY package.json package-lock.json* ./ RUN npm install && \ npm cache clean --force # ===== BUILD STAGE ===== FROM node:20-alpine AS builder WORKDIR /app # Install build dependencies RUN apk add --no-cache libc6-compat openssl # Copy ALL dependencies from deps stage (needed for build) COPY --from=deps /app/node_modules ./node_modules # Copy source code COPY . . # Generate Prisma Client RUN npx prisma generate # Build Next.js application (standalone output enabled in next.config.mjs) ENV NODE_ENV=production ENV NEXT_TELEMETRY_DISABLED=1 RUN npm run build # ===== RUNNER STAGE ===== FROM node:20-alpine AS runner WORKDIR /app # Install only runtime dependencies RUN apk add --no-cache openssl dumb-init ENV NODE_ENV=production ENV NEXT_TELEMETRY_DISABLED=1 # Create non-root user RUN addgroup --system --gid 1001 nodejs && \ adduser --system --uid 1001 nextjs # Copy only the standalone output (includes minimal node_modules) COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static # Copy Prisma files (needed for migrations/queries) COPY --from=builder --chown=nextjs:nodejs /app/prisma ./prisma COPY --from=builder --chown=nextjs:nodejs /app/node_modules/.prisma ./node_modules/.prisma USER nextjs EXPOSE 3000 ENV PORT=3000 ENV HOSTNAME="0.0.0.0" # Use dumb-init and run the standalone server CMD ["dumb-init", "node", "server.js"]