# Drone CI Pipeline Build Time Optimization ## Current Issues (6+ minutes to build) ### Time Breakdown from Logs: 1. **Docker daemon startup**: ~1.5 seconds 2. **`npm install next -g`**: ~1 minute 13 seconds ❌ (UNNECESSARY) 3. **`npm ci`**: ~2 minutes 4. **Image pulls**: ~30 seconds 5. **Build overhead**: Multiple intermediate containers 6. **No layer caching**: Every build starts from scratch ## Optimizations Implemented ### 1. **Remove Unnecessary `npm install next -g`** (Saves ~1-1.5 minutes) - **Issue**: The current Dockerfile globally installs Next.js, which is already in package.json - **Fix**: Removed this step entirely in the optimized Dockerfile - **Savings**: ~70-80 seconds ### 2. **Multi-Stage Docker Build** (Saves ~30-60 seconds + smaller image) - **Issue**: Single-stage build includes build dependencies in final image - **Fix**: - Stage 1 (deps): Install dependencies - Stage 2 (builder): Build application - Stage 3 (runner): Minimal runtime image - **Benefits**: - Smaller final image (only production dependencies) - Better layer caching - Faster subsequent builds ### 3. **Enable Docker Layer Caching** (Saves ~2-3 minutes after first build) - **Issue**: No caching between builds means npm packages reinstall every time - **Fix**: Added `cache_from` in .drone.yml pointing to previous images - **Benefits**: - Dependencies cached if package.json unchanged - Source code changes don't trigger dependency reinstall - Build steps only run if inputs change ### 4. **Enable Docker BuildKit** (Saves ~10-30 seconds) - **Issue**: Using legacy Docker builder - **Fix**: Set `DOCKER_BUILDKIT=1` environment variable - **Benefits**: - Parallel build stages - Better caching - Faster builds ### 5. **Optimized Layer Order** (Maximizes cache hits) - **Issue**: Copying all files before installing dependencies - **Fix**: Copy package.json first, install deps, then copy source - **Benefits**: - Dependencies only reinstall when package files change - Code changes don't invalidate dependency cache ## Expected Build Time Improvements ### First Build (Cold Cache): - **Current**: ~6 minutes - **Optimized**: ~4-4.5 minutes - **Improvement**: ~25-30% ### Subsequent Builds (Warm Cache): - **Current**: ~6 minutes (no caching) - **Optimized with code changes only**: ~1.5-2 minutes - **Optimized with dependency changes**: ~3-3.5 minutes - **Improvement**: ~60-75% for typical code-only changes ## Implementation Steps ### Quick Win (Immediate ~1.5 min improvement): 1. Replace current Dockerfile: ```bash mv docker/Dockerfile docker/Dockerfile.old mv docker/Dockerfile.optimized docker/Dockerfile ``` ### Full Optimization (Up to 75% improvement): 1. Replace Dockerfile (as above) 2. Replace .drone.yml with caching enabled: ```bash mv .drone.yml .drone.yml.old mv .drone.yml.optimized .drone.yml ``` 3. Commit and push: ```bash git add docker/Dockerfile .drone.yml git commit -m "optimize: improve CI build time with multi-stage builds and layer caching" git push ``` ## Additional Optimization Options (Future) ### Option 1: Enable Next.js Standalone Output (Extra 20-30% improvement) Add to `next.config.mjs`: ```javascript const nextConfig = { output: 'standalone', eslint: { ignoreDuringBuilds: true, }, typescript: { ignoreBuildErrors: true, }, } ``` This creates a minimal production build with only required files. ### Option 2: Use npm Registry Mirror/Cache (Saves ~30-60 seconds) Add to Dockerfile before `npm ci`: ```dockerfile RUN npm config set registry https://your-npm-mirror.com ``` ### Option 3: Pre-built Base Image (Saves ~1-2 minutes) Create a custom base image with common dependencies pre-installed: ```dockerfile FROM node:22-alpine RUN apk add --no-cache python3 make g++ # Pre-install common dependencies RUN npm install -g next@15.3.2 ``` ### Option 4: Parallel Testing (if applicable) If you add testing steps, run them in parallel with builds using Drone's parallel step feature. ## Verification After implementing, monitor build times in Drone CI dashboard: 1. **First build after changes**: Should be ~4-4.5 minutes 2. **Build with code-only changes**: Should be ~1.5-2 minutes 3. **Build with package.json changes**: Should be ~3-3.5 minutes ## Rollback Plan If issues occur: ```bash mv docker/Dockerfile.old docker/Dockerfile mv .drone.yml.old .drone.yml git add docker/Dockerfile .drone.yml git commit -m "rollback: revert pipeline optimizations" git push ``` ## Notes - BuildKit may not be available on older Docker versions (requires Docker 18.09+) - Layer caching requires the registry to support it (most modern registries do) - First build will still be slow as it populates the cache - Consider scheduled cache warming builds if needed