Module 6 Lesson 2: Optimized Layer Order
Master the build cache. Learn how to structure your Dockerfile instructions to minimize 'Cache Invalidation' and keep your build times under 5 seconds.
Module 6 Lesson 2: Optimized Layer Order
In Module 3, we introduced the concept of the Build Cache. Now, we will master it. Building an image efficiently involves understanding exactly which parts of your app change the most frequently.
1. The Golden Rule of Caching
Place the most frequently changed instructions as late as possible in the Dockerfile.
Frequency of Change (from least to most):
- Operating System / Base Image (
FROM) - System Packages (
RUN apt-get install) - Application Dependencies (
pip install,npm install) - Infrastructure Config (
ENV,WORKDIR) - Your Source Code (
COPY . .) -> This changes every few minutes!
2. Real-World Optimization: Node.js
The Naive Path (Slow)
FROM node:18
WORKDIR /app
COPY . . # If ANY file changes, we rebuild EVERYTHING below
RUN npm install # This takes 2 minutes every time!
CMD ["node", "server.js"]
The Optimized Path (Fast)
FROM node:18
WORKDIR /app
# Step 1: Copy only the Manifest
COPY package.json package-lock.json ./
# Step 2: Install dependencies (This layer remains cached for 95% of builds)
RUN npm install
# Step 3: Copy the rest of the source code
COPY . .
CMD ["node", "app.js"]
Why it works: You change your JavaScript code 100 times a day, but you only change your package.json (adding a new library) maybe once a week. By splitting the COPY, you save hours of build time every month.
Visualizing the Process
graph TD
Start[Input] --> Process[Processing]
Process --> Decision{Check}
Decision -->|Success| End[Complete]
Decision -->|Retry| Process
3. Combining RUN Commands (Atomic Layers)
Sometimes, you want to combine commands to ensure you don't "Cache" a bad state.
Bad:
RUN apt-get update
RUN apt-get install -y git
If you change the second line to apt-get install -y wget, Docker will reuse the cached update from 3 months ago! It might not find the new package.
Good:
RUN apt-get update && apt-get install -y \
git \
wget
This ensures that update and install always happen together in one fresh layer.
Exercise: The Python Optimizer
You are building a Python app.
- You have a
requirements.txtfile and asrc/folder. - Write an optimized Dockerfile that ensures
pip installonly runs whenrequirements.txtchanges. - Test it:
- Build the image.
- Change a print statement in
src/main.py. - Build again. Did it skip the
pip install?
- Why should you avoid putting
RUN apt-get upgrade -yin a Dockerfile? (Search for "Docker deterministic builds").
Summary
Optimized layer ordering is about Developer Productivity. Every second you spend waiting for a container to build is a second you aren't coding. By mastering the cache, you make Docker feel invisible.
Next Lesson: Filtering the noise: Working with .dockerignore.