Problem

Multiple applications deployed on the same server are each downloading dependencies independently, causing slow builds and wasted bandwidth.

Solutions Implemented

1. BuildKit Cache Mounts (HIGHEST IMPACT)

Enable Docker BuildKit and use cache mounts to share package caches across all builds on the same server.

For Next.js/React Apps (pnpm):

  
# In build stage, replace:RUN pnpm install

# With:RUN --mount=type=cache,id=pnpm,target=/root/.local/share/pnpm/store \
pnpm install --frozen-lockfile
  

For .NET Apps:

  
# In build stage, replace:RUN dotnet restore

# With:RUN --mount=type=cache,id=nuget,target=/root/.nuget/packages \
dotnet restore
  

2. Jenkins Pipeline Configuration

Update your Jenkinsfile to enable BuildKit:

  
    pipeline {
    agent any
    environment {
        DOCKER_BUILDKIT = '1'
    }
    stages {
        stage('Build') {
            steps {
                sh 'docker build --build-arg BUILDKIT_INLINE_CACHE=1 -t myapp .'
            }
        }
    }
}
  

3. Docker Daemon Configuration

On your server, edit /etc/docker/daemon.json :

  
    {"features": {
    "buildkit": true}}
  

Restart Docker:

  
    sudo systemctl restart docker
  

4. Multi-Stage Build Best Practices

✅ Your Dockerfiles already use multi-stage builds

✅ Dependencies are copied before source code

5. Layer Caching Order (Verify)

Ensure this order in all Dockerfiles:

  1. Install package manager (pnpm/dotnet)

  2. Copy package files only (package.json, pnpm-lock.yaml, *.csproj)

  3. Install dependencies (with cache mount)

  4. Copy source code

  5. Build application

Expected Performance Improvements

OptimizationFirst BuildSubsequent BuildsBenefit
Cache MountsSame60-90% fasterShares npm/pnpm/NuGet cache
Layer CachingSame40-70% fasterReuses unchanged layers
CombinedSame70-95% fasterMaximum efficiency

Quick Application Guide

Next.js Apps (pnpm-based):

Optimization Pattern:

  
    RUN --mount=type=cache,id=pnpm,target=/root/.local/share/pnpm/store \
    pnpm install --frozen-lockfile
  

Vite/React Apps (pnpm-based):

Same optimization as Next.js

.NET Apps:

Optimization Pattern:

  
    RUN --mount=type=cache,id=nuget,target=/root/.nuget/packages \
    dotnet restore
  

Implementation Steps

  1. Enable BuildKit (server-level - do this first):

          
            echo '{"features": {"buildkit": true}}' | sudo tee /etc/docker/daemon.json
    sudo systemctl restart docker
          
        
  2. Update Jenkinsfiles (add to environment):

          
            environment {
        DOCKER_BUILDKIT = '1'
    }
          
        
  3. Update Dockerfiles (for each app):

    • Add --mount=type=cache to install commands

    • Use --frozen-lockfile or --prod=false flags appropriately

  4. Verify Build Logs :

    • Look for CACHED messages in build output

    • Monitor build times improvement

Additional Optimizations

A. Use .dockerignore

Create .dockerignore in each project:

  
    node_modules
.next
.git
*.log
.env.local
dist
build
  

B. Prune Unused Images Regularly

Add Jenkins job:

  
    stage('Cleanup') {
    steps {
        sh 'docker system prune -af --filter "until=168h"'
    }
}
  

C. Use Registry Cache (Advanced)

For even faster builds, push cache to Docker registry:

  
    docker build \
  --cache-from myregistry/app:cache \
  --build-arg BUILDKIT_INLINE_CACHE=1 \
  -t myregistry/app:latest \
  --push .
  

Monitoring Success

After implementation, track:

Run this to see cache usage:

  
    docker system df -v