Speed Up Docker Builds with Layer Caching and dockerignore
Refactor a slow Dockerfile to leverage layer caching, add a .dockerignore to shrink the build context, and inspect the resulting image with docker history and docker diff.

Lab overview
Docker assembles an image by running your Dockerfile one instruction at a time, and every instruction becomes a read-only layer stacked on the one before it. BuildKit caches those layers and reuses them on the next build, but only for as long as their inputs stay unchanged. Each layer is keyed on its instruction plus the contents of any files it reads, so the moment a COPY picks up an edited file, that layer's hash changes and every layer beneath it is rebuilt from scratch. Instruction order is what decides the cost: place your source code above the dependency install and a one-line edit reinstalls every package, but put the dependencies first and the same edit rebuilds in seconds.
Ordering is only half the story. Before a build even starts, the Docker CLI bundles up the build context (every file in your project directory) and ships it to the daemon. Without a .dockerignore, that bundle drags along node_modules, .git, logs, and whatever else is lying in the folder, which slows every build, inflates your COPY instructions, and can quietly bake secrets into image layers. In this lab, you will build a deliberately slow Dockerfile and time what an unnecessary dependency reinstall costs, reorder its instructions into a cache-friendly version, add a .dockerignore to shrink the context, and finish by inspecting the finished layers with docker history and docker diff to see exactly what each build changed.
Objectives
Upon completion of this beginner level lab, you will be able to:
- Explain how Docker's layer cache is keyed and what triggers invalidation for
COPY,RUN, andARGinstructions. - Diagnose a slow Dockerfile by timing rebuilds after a one-line source change and reading the BuildKit
CACHED/DONEmarkers. - Refactor a Node.js Dockerfile so dependency installation lives in a stable upper layer that survives source edits.
- Author a
.dockerignorethat excludesnode_modules, VCS files, logs, and documentation from the build context. - Inspect a built image's layer history with
docker historyand map each layer back to a Dockerfile instruction. - Use
docker diffto compare the running container's filesystem against its image and identify writable-layer changes.
Who is this lab for?
This lab is designed for:
- Developers who have already written a basic Dockerfile and want to speed up their builds in everyday development.
- Platform engineers tuning CI build pipelines for image-heavy services.
Verified against your live environment
An automated validation engine inspects your actual resources and configurations as you work. Completion means the task was performed, not multiple choice, real-world proficiency.
More labs like this
Running Containers with docker run and kubectl
Run nginx:alpine first with docker run then with kubectl run on the same VM, and see how Kubernetes maps onto Docker concepts.
Deploy Multi-Container Apps with Docker Compose
Author a compose.yaml that runs nginx, a Python API, and Postgres as a single declarative multi-service stack.
Externalize Docker Configuration with Environment Variables and Compose Secrets
Externalize Docker app config the 12-factor way using -e, --env-file, Compose env_file, and Compose secrets.
Environment
Every lab includes
- Real environment, pre-credentialed
- Automated checks on every step
- Isolated sandbox, auto cleanup
- AI-recommended next steps
Lab curriculum
- 01
Getting Started with Docker IDE
- 02
Build a Slow Dockerfile and Watch Every Edit Bust the Cache
1 automated check
- 03
Refactor to a Fast Dockerfile and Cache the Dependency Install Layer
1 automated check
- 04
Add a dockerignore File and Shrink the Build Context
1 automated check
- 05
Inspect Image Layers with docker history and docker diff
1 automated check
Not the lab you were looking for?
Browse 200+ hands-on labs across AWS, Azure, Kubernetes, Docker, and cloud security.