# ============================================================================= # Multi-stage Dockerfile for Next.js 15 - Production Optimized # ============================================================================= # Stage 1: Dependencies - Install all dependencies # Stage 2: Builder - Build the application # Stage 3: Runner - Production runtime # ============================================================================= # ----------------------------------------------------------------------------- # Stage 1: Dependencies # ----------------------------------------------------------------------------- FROM node:22-alpine AS deps # Install system dependencies for node-gyp RUN apk add --no-cache libc6-compat WORKDIR /app # Copy dependency files COPY package.json package-lock.json* ./ # Install dependencies # Use npm ci for reproducible builds RUN npm ci --legacy-peer-deps || npm install --legacy-peer-deps # ----------------------------------------------------------------------------- # Stage 2: Builder # ----------------------------------------------------------------------------- FROM node:22-alpine AS builder WORKDIR /app # Copy dependencies from deps stage COPY --from=deps /app/node_modules ./node_modules # Copy source code COPY . . # Set build-time environment variables ENV NEXT_TELEMETRY_DISABLED=1 ENV NODE_ENV=production # Build application RUN npm run build # ----------------------------------------------------------------------------- # Stage 3: Runner (Production) # ----------------------------------------------------------------------------- FROM node:22-alpine AS runner # Install runtime dependencies RUN apk add --no-cache \ libc6-compat \ dumb-init WORKDIR /app # Set production environment ENV NODE_ENV=production ENV NEXT_TELEMETRY_DISABLED=1 ENV PORT=3000 ENV HOSTNAME="0.0.0.0" # Create non-root user for security RUN addgroup --system --gid 1001 nodejs && \ adduser --system --uid 1001 nextjs # Copy necessary files from builder COPY --from=builder --chown=nextjs:nodejs /app/next.config.js ./ COPY --from=builder --chown=nextjs:nodejs /app/public ./public COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next COPY --from=builder --chown=nextjs:nodejs /app/package.json ./ COPY --from=builder --chown=nextjs:nodejs /app/node_modules ./node_modules # Switch to non-root user USER nextjs # Expose port EXPOSE 3000 # Health check HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \ CMD node -e "require('http').get('http://localhost:3000/', (res) => { process.exit(res.statusCode === 200 ? 0 : 1); }).on('error', () => { process.exit(1); });" # Use dumb-init to handle signals properly ENTRYPOINT ["dumb-init", "--"] # Start Next.js in production mode CMD ["node_modules/.bin/next", "start"]