# ============================================================================= # Dockerfile for Next.js 16 - Production Optimized for Coolify # ============================================================================= # Multi-stage build for minimal image size and maximum performance # Compatible with: Coolify, Docker Compose, Kubernetes # Node Version: 20 LTS (Alpine) # Package Manager: npm (native to project) # ============================================================================= # ----------------------------------------------------------------------------- # Stage 1: Dependencies (deps) # Install only production dependencies with locked versions # ----------------------------------------------------------------------------- FROM node:20-alpine AS deps # Install system dependencies required by Node.js native modules RUN apk add --no-cache libc6-compat WORKDIR /app # Copy package files for dependency installation COPY package.json package-lock.json ./ # Install dependencies with npm ci (clean install from lock file) # This ensures reproducible builds and faster installs RUN npm ci --only=production --ignore-scripts && \ npm cache clean --force # ----------------------------------------------------------------------------- # Stage 2: Builder (builder) # Build the Next.js application with all dev dependencies # ----------------------------------------------------------------------------- FROM node:20-alpine AS builder # Install system dependencies for Prisma and build tools RUN apk add --no-cache \ libc6-compat \ openssl WORKDIR /app # Copy package files COPY package.json package-lock.json ./ # Install ALL dependencies (including devDependencies for build) RUN npm ci --ignore-scripts && \ npm cache clean --force # Copy application source COPY . . # Set build-time environment variables ENV NEXT_TELEMETRY_DISABLED=1 ENV NODE_ENV=production # Generate Prisma Client RUN npx prisma generate # Build Next.js application with standalone output # This creates a minimal server bundle in .next/standalone RUN npm run build # ----------------------------------------------------------------------------- # Stage 3: Runner (production) # Minimal runtime image with only necessary files # ----------------------------------------------------------------------------- FROM node:20-alpine AS runner # Install runtime dependencies RUN apk add --no-cache \ libc6-compat \ openssl \ wget \ dumb-init && \ rm -rf /var/cache/apk/* WORKDIR /app # Set production environment variables 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 Prisma runtime files COPY --from=builder --chown=nextjs:nodejs /app/node_modules/.prisma ./node_modules/.prisma COPY --from=builder --chown=nextjs:nodejs /app/node_modules/@prisma ./node_modules/@prisma # Copy standalone Next.js server COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ # Copy static files COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static # Copy public directory COPY --from=builder --chown=nextjs:nodejs /app/public ./public # Copy Prisma schema for runtime (if needed) COPY --from=builder --chown=nextjs:nodejs /app/prisma ./prisma # Copy scripts directory for seed and admin tools COPY --from=builder --chown=nextjs:nodejs /app/scripts ./scripts # Switch to non-root user USER nextjs # Expose application port EXPOSE 3000 # Health check for container orchestration HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \ CMD wget --no-verbose --tries=1 --spider http://localhost:3000/api/health || exit 1 # Use dumb-init to handle signals properly ENTRYPOINT ["dumb-init", "--"] # Start the Next.js server CMD ["node", "server.js"]