# ============================================================================ # Multi-stage build for optimized production Docker image # ============================================================================ # Stage 1: Dependencies FROM node:20-alpine AS dependencies WORKDIR /app # Copy only package files COPY package*.json ./ # Install dependencies (using npm ci for production) RUN npm ci --prefer-offline --no-audit # ============================================================================ # Stage 2: Production FROM node:20-alpine AS production # Install curl for healthcheck and dumb-init for signal handling RUN apk add --no-cache curl dumb-init # Set working directory WORKDIR /app # Set Node.js environment to production ENV NODE_ENV=production # Copy node_modules from dependencies stage COPY --from=dependencies /app/node_modules ./node_modules # Copy package files COPY package*.json ./ # Copy application code COPY . . # Create non-root user for security RUN addgroup -g 1001 -S nodejs && adduser -S nodejs -u 1001 USER nodejs # Expose port EXPOSE 3000 # Health check HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \ CMD curl -f http://localhost:3000 || exit 1 # Use dumb-init to handle signals properly (graceful shutdown) ENTRYPOINT ["/usr/bin/dumb-init", "--"] # Start application CMD ["node", "server.js"]