# Multi-stage build for production # Use Alpine for smaller image and better resource management FROM node:18-alpine AS builder WORKDIR /app # Reduce npm file descriptor usage and disable unnecessary network/audit work ENV npm_config_fund=false \ npm_config_audit=false \ npm_config_progress=false # Copy package files COPY package*.json ./ # Install dependencies with aggressive network timeout optimization RUN npm cache clean --force \ && npm config set maxsockets 1 \ && npm config set fetch-retries 10 \ && npm config set fetch-retry-mintimeout 30000 \ && npm config set fetch-retry-maxtimeout 300000 \ && npm config set fetch-timeout 600000 \ && npm config set registry https://registry.npmjs.org/ \ && npm install --no-audit --no-fund --progress=false --timeout=600000 \ && npm cache clean --force # Copy source code COPY . . # Run unit tests during build (fails build if tests fail) # Temporarily disabled due to Babel configuration issues # RUN npm test -- --coverage --watchAll=false --testTimeout=30000 || \ # (echo "❌ FRONTEND TESTS FAILED - Build aborted" && exit 1) # Build production bundle using the legacy OpenSSL provider for Node 18+ compatibility RUN NODE_OPTIONS=--openssl-legacy-provider npm run build # Production stage FROM node:18-alpine AS production WORKDIR /app # Keep npm quiet and reduce file operations in runtime image too ENV npm_config_fund=false npm_config_audit=false npm_config_progress=false # Install serve to serve static files with aggressive timeout optimization RUN npm config set fetch-timeout 600000 \ && npm config set fetch-retries 10 \ && npm config set maxsockets 1 \ && npm install -g serve --no-fund --no-audit --progress=false --timeout=600000 # Create non-root user for OpenShift compatibility (Alpine-based) RUN addgroup -g 1001 nodejs && \ adduser -D -u 1001 -G nodejs -h /home/reactjs reactjs # Copy built application from builder stage COPY --from=builder /app/build ./build # Change ownership to non-root user RUN chown -R reactjs:nodejs /app # Switch to non-root user USER reactjs # Expose port EXPOSE 3000 # Start production server CMD ["serve", "-s", "build", "-l", "3000"]