# syntax=docker/dockerfile:1.7-labs # Ultra-optimized Dockerfile for maximum build speed on multi-core systems # ============================================================================== # STAGE 1: Base system with parallel dependency installation # ============================================================================== FROM node:20-slim AS base SHELL ["/bin/bash", "-c"] # Enable parallel processing ENV NPM_CONFIG_JOBS=max ENV NPM_CONFIG_MAXSOCKETS=50 ENV NPM_CONFIG_CACHE=/tmp/.npm # Create app directory and user in parallel RUN mkdir -p /app /tmp/.npm && \ groupadd --gid 1000 node && \ useradd --uid 1000 --gid node --shell /bin/bash --create-home node WORKDIR /app # ============================================================================== # STAGE 2: System dependencies (parallelized) # ============================================================================== FROM base AS system-deps # Install system dependencies with maximum parallelization RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ --mount=type=cache,target=/var/lib/apt/lists,sharing=locked \ apt-get update && \ apt-get install -y --no-install-recommends \ # Core system tools wget ca-certificates curl gnupg \ # Chromium dependencies (parallel install) chromium \ fonts-liberation libappindicator3-1 libasound2 \ libatk-bridge2.0-0 libatk1.0-0 libcups2 libdbus-1-3 \ libdrm2 libgbm1 libnspr4 libnss3 libx11-xcb1 \ libxcomposite1 libxdamage1 libxrandr2 xdg-utils \ libxss1 libgconf-2-4 libxtst6 libasound2 \ libpangocairo-1.0-0 libgdk-pixbuf2.0-0 libgtk-3-0 \ libxshmfence1 && \ # Cleanup in same layer apt-get clean && \ rm -rf /var/lib/apt/lists/* # ============================================================================== # STAGE 3: Node.js dependencies (heavily optimized) # ============================================================================== FROM system-deps AS node-deps # Install pnpm for faster package management RUN --mount=type=cache,target=/tmp/.npm \ npm install -g pnpm@latest # Copy dependency files COPY --chown=node:node package.json pnpm-lock.yaml* package-lock.json* yarn.lock* .npmrc* ./ # Install dependencies with maximum parallelization RUN --mount=type=cache,target=/root/.pnpm-store \ --mount=type=cache,target=/tmp/.npm \ # Use pnpm with parallel fetching if [ -f pnpm-lock.yaml ]; then \ PNPM_STORE_DIR=/root/.pnpm-store pnpm install --frozen-lockfile --prefer-offline; \ elif [ -f package-lock.json ]; then \ npm ci --prefer-offline --no-audit --no-fund --maxsockets 50; \ else \ npm install --prefer-offline --no-audit --no-fund --maxsockets 50; \ fi # ============================================================================== # STAGE 4: Playwright setup (parallel browser installation) # ============================================================================== FROM node-deps AS browser-deps # Install Playwright with parallel browser downloads ENV PLAYWRIGHT_BROWSERS_PATH=/ms-playwright ENV PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS=true RUN --mount=type=cache,target=/ms-playwright \ npx playwright install chromium --with-deps && \ # Parallel browser validation npx playwright install-deps chromium & # ============================================================================== # STAGE 5: Application build (parallelized) # ============================================================================== FROM browser-deps AS builder # Copy source code COPY --chown=node:node . . # Generate Prisma client in parallel with Next.js build RUN --mount=type=cache,target=/app/.next/cache \ --mount=type=cache,target=/tmp/.npm \ # Run Prisma generation and Next.js build in parallel npx prisma generate & \ NEXT_BUILD_ID="docker-$(date +%s)" npm run build && \ wait # ============================================================================== # STAGE 6: Production runtime (minimal) # ============================================================================== FROM system-deps AS runner # Copy only necessary files from previous stages COPY --from=builder --chown=node:node /app/package.json ./ COPY --from=builder --chown=node:node /app/.next/standalone ./ COPY --from=builder --chown=node:node /app/.next/static ./.next/static COPY --from=builder --chown=node:node /app/public ./public COPY --from=builder --chown=node:node /app/prisma ./prisma COPY --from=builder --chown=node:node /app/node_modules ./node_modules COPY --from=browser-deps --chown=node:node /ms-playwright /ms-playwright # Set environment variables for production ENV NODE_ENV=production ENV NEXT_TELEMETRY_DISABLED=1 ENV PLAYWRIGHT_BROWSERS_PATH=/ms-playwright ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium ENV PORT=3000 # Create necessary directories RUN mkdir -p /app/screenshots /app/videos && \ chown -R node:node /app # Switch to non-root user USER node # Health check HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \ CMD curl -f http://localhost:3000/api/health || exit 1 EXPOSE 3000 # Start with optimized Node.js flags CMD ["node", "--max-old-space-size=2048", "--enable-source-maps", "server.js"]