Dockerfile by Example: Layer Caching Strategy
Docker caches the result of each instruction to speed up builds. This code example shows how to order instructions to maximize cache hits and optimize build times.
Code
FROM python:3.9-slim
WORKDIR /app
# 1. Copy dependency files FIRST
# These change less frequently than source code
COPY requirements.txt .
# 2. Install dependencies
# This layer will be cached unless requirements.txt changes
RUN pip install --no-cache-dir -r requirements.txt
# 3. Copy source code LAST
# This changes frequently. Putting it last prevents invalidating
# the expensive 'pip install' layer above.
COPY . .
CMD ["python", "app.py"]Explanation
Docker builds images using a layered approach where each instruction in the Dockerfile creates a new layer. Docker implements a caching mechanism that reuses existing layers if the instruction and its parent layers haven't changed. To optimize build speed, instructions should be ordered from least frequently changing to most frequently changing, ensuring that expensive operations like downloading dependencies are not re-executed unnecessarily.
Layer caching behaviors include:
- Changes in a layer invalidate the cache for all subsequent layers
COPYandADDinstructions check file checksums to determine cache validityRUNinstructions check the command string itself for changes- Build arguments can be used to intentionally bust the cache at specific points
In this example, copying requirements.txt and running pip install before copying the rest of the source code creates a dependency layer. This layer remains cached as long as the requirements file doesn't change, allowing developers to iterate on application code without waiting for dependencies to reinstall. If COPY . . were placed at the top, every source code change would invalidate the cache, forcing a full rebuild of all subsequent layers.
Code Breakdown
COPY requirements.txt . isolates dependency definition to its own cacheable layer.RUN pip install ... executes only if the previous layer changed.COPY . . adds frequently changing source code after the expensive steps.WORKDIR /app sets context, ensuring subsequent commands run in correct location.
