You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

4.7 KiB

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:
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:
mv .drone.yml .drone.yml.old
mv .drone.yml.optimized .drone.yml
  1. Commit and push:
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:

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:

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:

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:

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