Docker  

Docker Build Optimization Guide

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):

  • llmcostoptimizer.com ✅ (optimized)

  • letsreact.org

  • ode2

  • All other Next.js apps

Optimization Pattern:

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

Vite/React Apps (pnpm-based):

  • aiagentsconference.live

  • aiagentsdiscovery.com

  • viberondemand.com (if React)

Same optimization as Next.js

.NET Apps:

  • viberondemand.com (if .NET)

  • Sharp-Rewards-API-Staging

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:

  • Build duration (should decrease by 60-90%)

  • Network bandwidth usage (should decrease significantly)

  • Disk space usage (cache mounts use more space but worth it)

Run this to see cache usage:

  
    docker system df -v