Dropping Docker Build Times from 30s to 2s

Published: (June 5, 2026 at 01:41 PM EDT)
2 min read
Source: Dev.to

Source: Dev.to

If your Docker build takes 30+ seconds every time you change a single line of code, your Dockerfile is working against you. The secret to lightning-fast builds lies in mastering layer caching. Here are the five core rules to optimize your Dockerfiles for maximum performance and predictability. When Docker builds an image, it caches the instructions as layers and reuses them if their content hash hasn’t changed. However, if a single layer changes, all subsequent layers get rebuilt. Because of this cascading effect, you must sort your instructions from the least volatile (changes rarely) to the most volatile (changes constantly). The most common mistake developers make is copying everything at once, which busts the cache on every code commit and forces dependencies to reinstall. Instead, split your COPY steps: First, copy the manifest files that contain dependency metadata (e.g., pyproject.toml, package.json). Run your package manager install command (e.g., pip install). Finally, copy the actual code files. Since code files change frequently in development, putting them last ensures your heavy dependency installation layer stays cached.

1. Copy ONLY dependency manifest

COPY pyproject.toml uv.lock ./

2. Install dependencies (Cached!)

RUN pip install —no-cache-dir fastapi uvicorn[standard]

3. Copy application code (Volatile)

COPY . .

.dockerignore

Without a .dockerignore file, you risk sending massive or sensitive directories to the Docker build context. Always exclude directories like .git, .env, .venv, and node_modules. Some of these contain too much irrelevant data that slows down the build, while others (like .env) contain secrets that should never be baked into your image. Every RUN instruction creates its own read-only layer. If you run an update, install a package, and clean up the cache across three different RUN instructions, the removal only deletes the files in that specific layer. The preceding layers remain unnecessarily bloated. To keep images small, chain your commands and clean up in the same step: RUN apt-get update &&
apt-get install -y —no-install-recommends curl &&
rm -fr /var/lib/apt/lists/*

Never rely on generic tags like python:latest or node:latest. The latest tag is a moving target. Using it risks silently breaking the reproducibility and predictability of your builds when the underlying OS or language version updates unexpectedly. Always pin to specific, immutable versions (e.g., python:3.12.7-slim-bookworm) to ensure your deployments are bulletproof.

0 views
Back to Blog

Related posts

Read more »

Mobile Midsommer Madness

!Cover image for Mobile Midsommer Madnesshttps://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploa...