Optimized Builds
[!NOTE] This module explores the core principles of Optimized Builds, deriving solutions from first principles and hardware constraints to build world-class, production-ready expertise.
1. The Three Pillars of Optimization
When building Docker images, you are optimizing for three things:
- Speed: Fast build times (CI/CD efficiency).
- Size: Small images (Faster pulls, lower storage costs).
- Security: Reduced attack surface.
This chapter focuses on Speed and Structure. The next chapter covers Multi-Stage builds (Size).
2. The Build Context
Have you ever seen this message hang for a long time?
Sending build context to Docker daemon 500MB...
What’s happening?
The Docker CLI zips up everything in your current directory and sends it to the Docker Daemon (which might be on a remote server). If you have node_modules, .git, or build artifacts locally, you are uploading gigabytes of junk.
The Solution: .dockerignore
Just like .gitignore. Create a .dockerignore file in the root:
.git
node_modules
build
dist
*.md
Result: Sending build context... 20KB. Instant.
3. Layer Caching (The Golden Rule)
Docker caches every layer. When you rebuild, Docker checks if it can reuse a cached layer.
The Golden Rule: If a layer changes, ALL subsequent layers are invalidated and must be rebuilt.
Optimizing Order
You must order instructions from Least Likely to Change to Most Likely to Change.
Interactive: The Cache Cascade
Drag the blocks to reorder them. Try to find the optimal order to prevent a cache miss when "Source Code" changes.
4. Minimizing Layers (Chaining)
Each RUN instruction creates a committed layer. If you create a file in one layer and delete it in the next, the file still exists in the image history (it’s just hidden).
The “&&” Operator
Chain commands to ensure temporary files are deleted in the same layer.
Bad (3 Layers, 100MB + 0MB + 0MB)
RUN apt-get update
RUN apt-get install -y python3
RUN rm -rf /var/lib/apt/lists/*
Good (1 Layer, 100MB)
RUN apt-get update && \
apt-get install -y python3 && \
rm -rf /var/lib/apt/lists/*
In the “Bad” example, the apt lists are baked into Layer 1. Deleting them in Layer 3 hides them, but doesn’t free the space.
Summary
- Context: Use
.dockerignore. - Order: Place volatile instructions (COPY code) as late as possible.
- Chain: Combine related commands to keep layers clean.