From 9ca310636183f4970db925ce8fa368e23645eb02 Mon Sep 17 00:00:00 2001 From: Thomas Hallock Date: Fri, 24 Oct 2025 13:03:35 -0500 Subject: [PATCH] perf: optimize Docker image size to reduce build failures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reduce image size from ~1.8GB to prevent GHCR push timeouts and failures. Changes: - Add production dependencies stage (--prod flag) - Remove build tools (make, g++) from runtime image - Copy only Python scripts from packages/core (not entire package) - Copy only Typst templates from packages/templates - Enhance .dockerignore to exclude tests, storybook, build artifacts Expected benefits: - 30-50% reduction in image size - Faster GHCR push times (< 10 minutes) - Reduced risk of timeout failures - Same runtime functionality 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .dockerignore | 22 +++++++++++++++++++++- Dockerfile | 42 ++++++++++++++++++++++++++++++++---------- 2 files changed, 53 insertions(+), 11 deletions(-) diff --git a/.dockerignore b/.dockerignore index dd7dfdd1..ec8a43e8 100644 --- a/.dockerignore +++ b/.dockerignore @@ -19,12 +19,18 @@ yarn-error.log* # Testing coverage .nyc_output +**/__tests__ +**/*.test.ts +**/*.test.tsx +**/*.spec.ts +**/*.spec.tsx # IDE .vscode .idea *.swp *.swo +.claude # OS .DS_Store @@ -46,7 +52,21 @@ packages/core/.venv/ # Storybook storybook-static +**/*.stories.tsx +**/*.stories.ts +.storybook # Deployment files nas-deployment/ -DEPLOYMENT_PLAN.md \ No newline at end of file +DEPLOYMENT_PLAN.md + +# SQLite database files (created at runtime) +**/data/*.db +**/data/*.db-shm +**/data/*.db-wal + +# Build artifacts (rebuilt during Docker build) +**/dist +**/.next +**/build +**/styled-system \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index e3abc82d..840e3913 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,7 +16,7 @@ COPY packages/core/client/node/package.json ./packages/core/client/node/ COPY packages/abacus-react/package.json ./packages/abacus-react/ COPY packages/templates/package.json ./packages/templates/ -# Install dependencies (will use .npmrc with hoisted mode) +# Install ALL dependencies for build stage RUN pnpm install --frozen-lockfile # Builder stage @@ -44,12 +44,32 @@ RUN cd apps/web && npx @pandacss/dev # Build using turbo for apps/web and its dependencies RUN turbo build --filter=@soroban/web +# Production dependencies stage - install only runtime dependencies +FROM node:18-alpine AS deps +WORKDIR /app + +# Install build tools temporarily for better-sqlite3 installation +RUN apk add --no-cache python3 py3-setuptools make g++ + +# Install pnpm +RUN npm install -g pnpm@9.15.4 + +# Copy package files +COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./ +COPY apps/web/package.json ./apps/web/ +COPY packages/core/client/node/package.json ./packages/core/client/node/ +COPY packages/abacus-react/package.json ./packages/abacus-react/ +COPY packages/templates/package.json ./packages/templates/ + +# Install ONLY production dependencies +RUN pnpm install --frozen-lockfile --prod + # Production image FROM node:18-alpine AS runner WORKDIR /app -# Install Python, pip, build tools for better-sqlite3, Typst, and qpdf (needed at runtime) -RUN apk add --no-cache python3 py3-pip py3-setuptools make g++ typst qpdf +# Install ONLY runtime dependencies (no build tools needed) +RUN apk add --no-cache python3 py3-pip typst qpdf # Create non-root user RUN addgroup --system --gid 1001 nodejs @@ -69,15 +89,17 @@ COPY --from=builder --chown=nextjs:nodejs /app/apps/web/dist ./apps/web/dist # Copy database migrations COPY --from=builder --chown=nextjs:nodejs /app/apps/web/drizzle ./apps/web/drizzle -# Copy node_modules (for dependencies) -COPY --from=builder --chown=nextjs:nodejs /app/node_modules ./node_modules -COPY --from=builder --chown=nextjs:nodejs /app/apps/web/node_modules ./apps/web/node_modules +# Copy PRODUCTION node_modules only (no dev dependencies) +COPY --from=deps --chown=nextjs:nodejs /app/node_modules ./node_modules +COPY --from=deps --chown=nextjs:nodejs /app/apps/web/node_modules ./apps/web/node_modules -# Copy core package (needed for Python flashcard generation scripts) -COPY --from=builder --chown=nextjs:nodejs /app/packages/core ./packages/core +# Copy ONLY Python scripts from core package (not entire package) +COPY --from=builder --chown=nextjs:nodejs /app/packages/core/server ./packages/core/server +COPY --from=builder --chown=nextjs:nodejs /app/packages/core/requirements.txt ./packages/core/requirements.txt -# Copy templates package (needed for Typst templates) -COPY --from=builder --chown=nextjs:nodejs /app/packages/templates ./packages/templates +# Copy ONLY Typst templates from templates package (not entire package) +COPY --from=builder --chown=nextjs:nodejs /app/packages/templates/typst ./packages/templates/typst +COPY --from=builder --chown=nextjs:nodejs /app/packages/templates/package.json ./packages/templates/package.json # Install Python dependencies for flashcard generation RUN pip3 install --no-cache-dir --break-system-packages -r packages/core/requirements.txt