# =============================================== # Stage 1: Dependencies Installation # =============================================== FROM node:20-alpine AS dependencies # Install build dependencies RUN apk add --no-cache libc6-compat # Set working directory WORKDIR /app # Copy package files COPY package*.json ./ # Install all dependencies (including dev for build) RUN npm ci --legacy-peer-deps # =============================================== # Stage 2: Build Application # =============================================== FROM node:20-alpine AS builder WORKDIR /app # Copy dependencies from previous stage COPY --from=dependencies /app/node_modules ./node_modules # Copy source code COPY . . # Set build-time environment variables ARG NEXT_PUBLIC_API_URL ARG NEXT_PUBLIC_APP_URL ARG NEXT_PUBLIC_SENTRY_DSN ARG NEXT_PUBLIC_SENTRY_ENVIRONMENT ARG NEXT_PUBLIC_GA_MEASUREMENT_ID ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL \ NEXT_PUBLIC_APP_URL=$NEXT_PUBLIC_APP_URL \ NEXT_PUBLIC_SENTRY_DSN=$NEXT_PUBLIC_SENTRY_DSN \ NEXT_PUBLIC_SENTRY_ENVIRONMENT=$NEXT_PUBLIC_SENTRY_ENVIRONMENT \ NEXT_PUBLIC_GA_MEASUREMENT_ID=$NEXT_PUBLIC_GA_MEASUREMENT_ID \ NEXT_TELEMETRY_DISABLED=1 # Build the Next.js application RUN npm run build # =============================================== # Stage 3: Production Image # =============================================== FROM node:20-alpine AS production # Install dumb-init for proper signal handling RUN apk add --no-cache dumb-init curl # Create non-root user RUN addgroup -g 1001 -S nodejs && \ adduser -S nextjs -u 1001 # Set working directory WORKDIR /app # Copy built application from builder COPY --from=builder --chown=nextjs:nodejs /app/public ./public COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static # Switch to non-root user USER nextjs # Expose port EXPOSE 3000 # Health check HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \ CMD curl -f http://localhost:3000/api/health || exit 1 # Set environment variables ENV NODE_ENV=production \ PORT=3000 \ HOSTNAME="0.0.0.0" # Use dumb-init to handle signals properly ENTRYPOINT ["dumb-init", "--"] # Start the Next.js application CMD ["node", "server.js"]