From defaae05fe2c95c938387923a3895b28d0648f5e Mon Sep 17 00:00:00 2001 From: hamed <15238-genius.ha@users.noreply.drupalcode.org> Date: Wed, 10 Dec 2025 15:19:06 +0330 Subject: [PATCH] refactor: simplify Dockerfile for Next.js 14 and optimize build stages --- dockerfile | 92 +++++++++++++++--------------------------------------- 1 file changed, 26 insertions(+), 66 deletions(-) diff --git a/dockerfile b/dockerfile index 2d1cc46..2f9804a 100644 --- a/dockerfile +++ b/dockerfile @@ -1,88 +1,48 @@ -# ============================================================================= -# 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 -# ============================================================================= +# Dockerfile for Next.js 14 - Optimized for Production -# ----------------------------------------------------------------------------- -# Stage 1: Dependencies -# ----------------------------------------------------------------------------- -FROM node:22-alpine AS deps - -# Install system dependencies for node-gyp -RUN apk add --no-cache libc6-compat +# Use the official Node.js image with Alpine Linux for a smaller footprint +FROM node:22-alpine AS base +# Set the working directory in the container WORKDIR /app -# Copy dependency files -COPY package.json package-lock.json* ./ +# Copy package.json and package-lock.json (or yarn.lock) +COPY package*.json ./ -# Install dependencies -# Use npm ci for reproducible builds -RUN npm ci --legacy-peer-deps || npm install --legacy-peer-deps +# Install dependencies - leveraging Docker cache +RUN npm i --force -# ----------------------------------------------------------------------------- -# 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 the rest of the application code COPY . . -# Set build-time environment variables -ENV NEXT_TELEMETRY_DISABLED=1 -ENV NODE_ENV=production - -# Build application +# Build the Next.js application RUN npm run build -# ----------------------------------------------------------------------------- -# Stage 3: Runner (Production) -# ----------------------------------------------------------------------------- +# Stage 2: Production image - smaller and leaner FROM node:22-alpine AS runner -# Install runtime dependencies -RUN apk add --no-cache \ - libc6-compat \ - dumb-init - +# Set the working directory WORKDIR /app -# Set production environment -ENV NODE_ENV=production -ENV NEXT_TELEMETRY_DISABLED=1 -ENV PORT=3000 -ENV HOSTNAME="0.0.0.0" +# Set environment variables +ENV NODE_ENV $NODE_ENV +ENV NEXT_TELEMETRY_DISABLED 1 -# Create non-root user for security -RUN addgroup --system --gid 1001 nodejs && \ - adduser --system --uid 1001 nextjs +# Add a non-root user for security +RUN addgroup -g 1001 -S nodejs +RUN adduser -S nextjs -u 1001 -# Copy necessary files from builder (standalone mode) -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/standalone ./ -COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static +# Copy only the necessary files from the builder stage +COPY --from=base /app/next.config.js ./ +COPY --from=base /app/public ./public +COPY --from=base --chown=nextjs:nodejs /app/.next/standalone ./ +COPY --from=base --chown=nextjs:nodejs /app/.next/static ./.next/static -# Switch to non-root user +# Change ownership of all copied files to the non-root user USER nextjs -# Expose port +# Expose the port Next.js listens on 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 standalone mode +# Command to start the Next.js server in production mode CMD ["node", "server.js"] \ No newline at end of file