Summary of "Docker Image BEST Practices - From 1.2GB to 10MB"
Why it matters
Smaller Docker images reduce storage cost, speed deployments, improve scalability, and enhance security—especially in Kubernetes and CI/CD environments.
Key optimization concepts and steps (practical guide)
-
Choose a minimal base image
- Replace bulky base images (e.g.,
node:latest, full Python images) with smaller variants likenode:alpineorpython:alpineto cut image size dramatically. - Caveat: Alpine uses a different libc and system libraries and can cause compatibility issues with native modules.
- Alternative: Google Distroless images — even smaller (no shell, no package manager) but harder to set up.
- Replace bulky base images (e.g.,
-
Use layer caching smartly (Dockerfile ordering)
- Each Dockerfile instruction creates an immutable layer; unchanged layers are reused to speed rebuilds.
- Strategy:
COPYfiles that change least (e.g.,package.jsonorrequirements.txt) before copying source code so dependency installation can be cached. - Three things that invalidate caches: changes to the copied file(s), changes to the Dockerfile instruction, or changes to any previous layer.
- Order your Dockerfile with stable layers at the top and frequently changing layers toward the end.
-
Reduce build context with .dockerignore
- Exclude unnecessary local files (e.g.,
node_modules, local build artifacts, secrets) so Docker sends less context to the daemon — this speeds builds and prevents accidental inclusion of secrets.
- Exclude unnecessary local files (e.g.,
-
Understand layer immutability and combine cleanup steps
- Deleting files in later
RUNsteps does not remove them from earlier layers; the data still contributes to the final image size. - Combine filesystem modifications and cleanup into a single
RUNso only the desired final state of that layer is committed (this effectively “squashes” intermediate artifacts).
- Deleting files in later
-
Use multi-stage builds (the most impactful)
- Build stage: use Node/npm (or other toolchain) to compile/build artifacts.
- Final stage:
FROMa minimal runtime (e.g.,nginx, Distroless) andCOPYonly the built artifacts (static files). - Result: the final image contains only runtime + build artifacts; compilers, full dependency sets, and source are discarded — massive size reductions.
Tip: For development you can keep larger, convenience-focused images, then switch to minimal production images for deployment.
Practical results
- Example progression:
node:latest→ ~1+ GBnode:alpine→ ~155 MB- multi-stage with
nginx→ ~57 MB - further optimized with Slim → ~10 MB
- The presenter reduced a React app image from ~1.2 GB to ~10 MB using the techniques above.
Tools and utilities recommended
- dive — layer inspector / image explorer to analyze image layers and find optimization opportunities.
- Slim — inspects and optimizes container images (can minify images significantly, improve security, and provide tooling such as Xray and linting). The presenter used Slim to reach the final ~10 MB result.
Other tips / notes
- Beware of accidentally copying secrets — use
.dockerignoreand avoid relying on transient inclusion + deletion (earlier layers may retain secrets). - Layer squashing is effectively achieved by combining operations into single steps rather than deleting across layers.
- These techniques are generalizable across runtimes (Node, Python, etc.).
Video type
Practical tutorial / step-by-step guide with examples applied to a Node/React application and general guidance applicable to other runtimes.
Main speaker / sources
- The presenter: an experienced Docker user (unnamed) demonstrating the workflow.
- Referenced projects and tools: Alpine images, Google Distroless,
nginx, dive, and Slim.
Category
Technology
Share this summary
Is the summary off?
If you think the summary is inaccurate, you can reprocess it with the latest model.