Every instruction in a Dockerfile creates a layer — an intermediate image. Docker caches layers and reuses them on subsequent builds if the instruction and its inputs haven’t changed.
How the Cache Works
When building, Docker checks each instruction:
- If the instruction and its inputs haven’t changed — uses the cache (instant)
- If something has changed — rebuilds that layer and all subsequent ones
Instruction Order Matters
Bad order — any code change triggers a full dependency reinstall:
FROM python:3.11-slim
WORKDIR /app
COPY . . # ← copies everything at once
RUN pip install -r requirements.txt # ← rebuilds on every code change!
CMD ["python", "app.py"]
Correct order — dependencies are only rebuilt when requirements.txt changes:
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt . # ← copy only requirements.txt first
RUN pip install -r requirements.txt # ← cached if requirements didn't change
COPY . . # ← copy code after dependencies
CMD ["python", "app.py"]
Rule: order instructions from least frequently changed to most frequently changed.
Inspecting Layers
# Show image layers
docker history myapp:v1
# Detailed layer information
docker inspect myapp:v1
Cache Invalidation
# Build without cache
docker build --no-cache -t myapp:v1 .
# Force rebuild from a specific step — change the instruction or add an ARG:
ARG CACHEBUST=1
RUN apt-get update
Multi-stage Builds — Shrinking the Final Image
The build stage contains compilers and tooling. The final stage contains only the output.
# Build stage
FROM python:3.11 AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt
# Final image
FROM python:3.11-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . .
CMD ["python", "app.py"]
The final image contains no pip, no compilers, no intermediate files — only what’s needed to run.
Image Size Tips
- Use
slimoralpinebase images - Combine multiple
RUN apt-get installcalls into a single instruction - Clean up the package manager cache:
&& rm -rf /var/lib/apt/lists/* - Use
.dockerignore - Use multi-stage builds for compiled languages
💬 Comments (0)
No comments yet
Be the first to share your opinion about this article!