Skip to content

hemantj-cloud/docker-base

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 

Repository files navigation

✅ What I did:

  • Created a base Docker image (Dockerfile.base) with Node 20 Alpine and a non-root user for security
  • Installed @nitrostack/cli globally in base image to reuse across all projects and reduce build time
  • Optimized base image by:
    • Combining layers (apk + npm install)
    • Cleaning npm cache
    • Disabling audit/fund checks
    • Ensuring global binaries are available via PATH
  • Used this base image in the main multi-stage Dockerfile (builder + production stages)
  • Kept npm install and build steps in the main Dockerfile to handle project-specific dependencies
  • Optimized builds using:
    • Docker cache (COPY package*.json first)
    • BuildKit cache (--mount=type=cache) for faster npm installs
  • Ensured clean dependency installation inside Docker (avoiding local node_modules)
  • Ensured only production dependencies are included in the final image to reduce size
  • Added cleanup steps to remove unnecessary files from node_modules
  • Implemented conditional widget handling to avoid build failures if widgets are absent
  • Added healthcheck and non-root execution for better production reliability

📦 Size Improvements (Actual):

🔹 Old Image (before optimizations)

  • fresh-pizza:local
    • Disk Usage: 418MB
    • Content Size: 87.7MB

🔹 Using Custom Base Image (hemantwekan/node-base:20-alpine)

  • hemantwekan/fresh-pizza:1.4.0
    • Disk Usage: 313MB
    • Content Size: 69.6MB

🔹 Using Official Node Alpine (node:20-alpine)

  • hemantwekan/fresh-pizza:1.5.0
    • Disk Usage: 317MB
    • Content Size: 70.2MB

🔹 Using Base Image with CLI (v2 - initial approach)

  • hemantwekan/fresh-pizza:1.6.0
    • Disk Usage: 401MB
    • Content Size: 88.3MB

🔹 Using Optimized Base Image (v3 - improved)

  • hemantwekan/node-base:20-alpine-v3
  • hemantwekan/fresh-pizza:1.7.0
    • Disk Usage: 355MB
    • Content Size: 77MB

🚀 Impact:

  • Reduced ~100MB+ disk usage compared to initial build (~25% improvement)
  • Initial CLI integration increased size, but further optimizations reduced ~46MB from that spike
  • Improved build time by:
    • installing @nitrostack/cli once in base image instead of every build
    • optimizing Docker layer caching (package.json first)
    • using BuildKit cache for npm dependencies
  • Eliminated platform-specific issues (e.g., esbuild mismatch) by ensuring clean installs inside Docker
  • Achieved a balanced tradeoff between:
    • build performance ⚡
    • image size 📦
  • Maintained overall optimized and reusable Docker architecture

⚡ Build Performance (Real Observation):

  • After optimization, repeated builds complete in ~0.9 seconds
  • Most Docker steps show CACHED, meaning:
    • dependencies are not reinstalled
    • build step is skipped
    • only final image assembly runs

✅ Why builds are fast now:

  • Docker reuses layers when:
    • package.json is unchanged → skips npm ci
    • source code is unchanged → skips build
  • BuildKit cache avoids re-downloading npm packages
  • Base image already contains required global dependencies

⚠️ When rebuild will be triggered:

  • Changes in package.json → reinstall dependencies
  • Changes in dependencies → rebuild required
  • Changes in base image → cache invalidation
  • Changes in source code → rebuild only (not reinstall)

⚠️ Key decisions:

  • Moved @nitrostack/cli to base image since it is required in both build and runtime
  • Optimized base image to reduce its impact on final image size
  • Focused on time optimization via caching and layering, not just image size
  • Ensured fresh dependency installation inside Docker to avoid cross-platform issues
  • Kept project-specific dependencies in main Dockerfile to maintain flexibility and proper caching

🧠 Key Learnings:

  • Base image helps:

    • ✅ reduce repeated setup
    • ✅ improve consistency
    • ❌ limited impact on total build time
  • Major time improvements come from:

    • 🚀 Docker layer caching
    • 🚀 npm ci optimization
    • 🚀 BuildKit cache
  • Achieved near O(1) build time for cached builds (~1s)

  • Build becomes slower only when dependencies change (expected behavior)

  • Pasted Graphic 1

🧠 Note on base updates:

  • Frequent base image updates can invalidate cache and slow down builds, so it should be versioned and updated only when needed
  • Use versioned tags (e.g., 20-alpine-v3) for stability and rollback support

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors