FROM node:20-alpine WORKDIR /appCOPY package*.json ./RUN npm installCOPY . .RUN npm run buildEXPOSE 3000CMD ["npm", "run", "start"]
Multi-stage build for the same,
# Stage 1: Install dependencies and build the app FROM node:20-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build # Stage 2: Install production dependencies FROM node:20-alpine AS production-dependencies WORKDIR /app COPY package*.json ./ RUN npm ci --only=production # Stage 3: Prepare the final image FROM node:20-alpine WORKDIR /app # Copy built assets and production dependencies COPY --from=builder /app/.next ./.next COPY --from=builder /app/public ./publicCOPY --from=production-dependencies /app/node_modules ./node_modules COPY package*.json ./ # Set proper permissions and user RUN chown -R node:node /app USER node EXPOSE 3000 CMD ["npm", "run", "start"]
Advantages
Smaller Final Image: Instead of carrying all build tools and dev dependencies, your final image only contains what’s needed to run the application
Security: Fewer packages mean smaller attack surface
Clean Separation: Build process is separate from runtime environment