How to Fix Docker Build Cache Not Working Error
In this tutorial, you'll learn about How to Fix Docker Build Cache Not Working Error. We cover key concepts, practical examples, and best practices.
Your Docker builds take minutes even when only source code changed — layers are not being cached because of poor Dockerfile ordering, cache-busting instructions, or missing cache mounts.
The Problem
[+] Building 45.2s (12/12) FINISHED
=> [6/8] RUN npm install 28.3s
=> [7/8] COPY . . 0.1s
Every build re-runs npm install even when package.json did not change, because COPY . . runs before the install step and invalidates the cache.
Step-by-Step Fix
Step 1: Reorder Dockerfile for dependency caching
# WRONG — cache busted on every source change
FROM node:18
WORKDIR /app
COPY . .
RUN npm install
RUN npm run build
# RIGHT — dependencies cached separately
FROM node:18
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
COPY . .
RUN npm run build
Step 2: Use build cache mounts for package managers
FROM node:18
WORKDIR /app
RUN --mount=type=cache,target=/root/.npm \
--mount=type=bind,source=package.json,target=package.json \
--mount=type=bind,source=package-lock.json,target=package-lock.json \
npm ci
COPY . .
RUN npm run build
Step 3: Leverage Docker BuildKit
Set the environment variable:
DOCKER_BUILDKIT=1 docker build -t myapp .
Or enable by default in ~/.docker/config.json:
{
"features": {
"buildkit": true
}
}
Step 4: Use --cache-from for CI caching
docker build -t myapp:latest --cache-from myapp:latest .
Step 5: Inspect which layers are cached
docker build --progress=plain -t myapp . 2>&1 | grep "CACHED"
Expected:
#6 [5/8] COPY package.json package-lock.json ./
#6 CACHED
Step 6: Clear cache when needed
docker builder prune
Prevention Tips
- Copy dependency manifests before source code
- Use
--mount=type=cachefor package manager caches - Pin base image versions to avoid external cache busting
- Use
.dockerignoreto exclude unnecessary files - Keep frequently-changing files at the bottom of the Dockerfile
Common Mistakes with layer caching
- Forgetting that lazy evaluation defers computation until the value is forced, causing space leaks with unevaluated thunks
- Using
returnto exit a function early instead of wrapping a pure value in the monad - Mixing let bindings with <- bindings in do notation, producing type errors
These mistakes appear frequently in real-world DOCKER code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.
Practice Exercise
Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.
This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.
FAQ
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro