Back to Blog
team@tinypod.app

Understanding Docker Build Cache

Docker build cache makes image builds fast by reusing layers. Understanding how it works helps you write efficient Dockerfiles.

dockerbuildcacheoptimization

How Build Cache Works


Docker builds images layer by layer. If a layer hasn't changed, Docker reuses the cached version instead of rebuilding it.


Cache Hit

Docker compares the instruction and its inputs:

  • COPY: File checksums match? Cache hit.
  • RUN: Same command as before? Cache hit.
  • FROM: Same base image? Cache hit.

  • Cache Miss

    When any instruction changes, that layer AND all subsequent layers are rebuilt.


    The Cache Invalidation Chain


    This is the key insight:


    FROM node:20-alpine # Cached

    COPY package.json . # Cached (if file unchanged)

    RUN npm install # Cached (depends on previous layer)

    COPY . . # MISS (source code changed)

    RUN npm run build # MISS (because previous layer changed)


    Once COPY . . invalidates, everything after it rebuilds.


    Optimization Strategies


    1. Order by Change Frequency

    Put rarely-changing layers first, frequently-changing layers last.


    Good:

    COPY package.json .

    RUN npm install

    COPY . .


    Bad:

    COPY . .

    RUN npm install


    In the bad version, every source code change invalidates the npm install cache.


    2. Separate Dependencies from Code

    Install dependencies before copying source code. Dependencies change less frequently than source code.


    3. Use .dockerignore

    Exclude node_modules, .git, tests, and docs. Smaller build context = faster builds and fewer cache invalidations.


    4. Minimize RUN Layers

    Each RUN creates a layer. Combine related commands:


    RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*


    5. Use BuildKit

    DOCKER_BUILDKIT=1 enables improved caching, parallel builds, and cache mounts.


    Cache Mounts


    BuildKit cache mounts persist across builds:

    RUN --mount=type=cache,target=/root/.npm npm install


    npm's cache directory persists between builds. Dramatically faster repeated installs.


    These optimizations make your TinyPod deployments faster — smaller images build and pull quicker.