What is a Container Image Layer Explained Simply
Container image layers are the building blocks of Docker images. Learn how layers work, why they matter for build speed and security, and how to keep your images lean.
A Docker image isn't a single file. It's a stack of read-only layers, each representing one instruction in the Dockerfile. Understanding layers is what separates engineers who have 200MB images from those who have 2GB images.
What is a Layer?
Each RUN, COPY, and ADD instruction in a Dockerfile creates a new layer. A layer is a diff — it records only what changed from the previous layer.
FROM ubuntu:22.04 # Layer 1: base OS (77MB)
RUN apt-get update # Layer 2: updated package index
RUN apt-get install -y nginx # Layer 3: nginx + dependencies
COPY ./config /etc/nginx/ # Layer 4: your config files
CMD ["nginx", "-g", "daemon off;"] # metadata only, no new layerThe final image is: Layer 1 + Layer 2 + Layer 3 + Layer 4 stacked on top of each other.
Visualizing Layers
docker history nginx:latestIMAGE CREATED CREATED BY SIZE
a99a39d070bf 2 weeks ago CMD ["nginx" "-g" "daemon off;"] 0B
<missing> 2 weeks ago STASH /etc/nginx/conf.d/default.conf 1.09kB
<missing> 2 weeks ago RUN /bin/sh -c apt-get install nginx 58.3MB
<missing> 2 weeks ago RUN /bin/sh -c apt-get update 18.1MB
<missing> 2 weeks ago ADD file:ubuntu-22.04.tar.gz 77.8MB
Each line = one layer. SIZE shows how much that layer adds to the image.
Why Layers Matter: Caching
Docker caches every layer. If a layer hasn't changed, it reuses the cached version instead of re-running the instruction. This is what makes rebuilds fast.
CACHED [1/4] FROM ubuntu:22.04
CACHED [2/4] RUN apt-get update
CACHED [3/4] RUN apt-get install nginx
Step 4/4: COPY ./config /etc/nginx/ ← changed, runs again
Cache invalidation rule: Once any layer changes, Docker re-runs that layer AND every layer after it.
This is why order matters in Dockerfiles:
# BAD — changing any source file invalidates the npm install cache
FROM node:20
COPY . . # copy everything first
RUN npm install # re-runs whenever ANY file changes
# GOOD — npm install only re-runs when package.json changes
FROM node:20
COPY package.json package-lock.json ./
RUN npm install # cached until package.json changes
COPY . . # source code copied after installHow Layers Are Stored
Docker stores layers as compressed tar archives on disk:
# See layer storage on your system
ls /var/lib/docker/overlay2/
# Each directory = one layer
# "overlay2" = the storage driver (uses copy-on-write)Layers are content-addressed — identified by a SHA256 hash of their contents. This means:
- Two images sharing the same base layer share the same bytes on disk
- Pulling
ubuntu:22.04twice downloads it once
Shared Layers Across Images
Image A:
[ubuntu:22.04] → [nginx] → [config-A]
Image B:
[ubuntu:22.04] → [nginx] → [config-B]
Both images share the ubuntu:22.04 and nginx layers. On disk, those bytes exist once. Only config-A and config-B are separate.
This is also why Docker pull shows "already exists" for most layers when pulling an updated image — only the changed layers download.
The Writable Container Layer
When you run a container, Docker adds one writable layer on top of the read-only image layers:
[Read-Only Image Layers] ← shared across all containers
↓
[Writable Container Layer] ← unique per container, deleted when container stops
Writing to files inside a running container goes to this writable layer (copy-on-write). The original image layers never change.
This is why containers start instantly — no copying of the image, just a new writable layer pointer.
Layer Anti-Patterns (and Fixes)
Secrets in layers
# BAD — API key is baked into layer history forever
RUN export API_KEY=secret123 && curl -H "Authorization: $API_KEY" ...
# GOOD — use BuildKit secrets
RUN --mount=type=secret,id=api_key \
API_KEY=$(cat /run/secrets/api_key) && curl -H "Authorization: $API_KEY" ...Even if you unset the variable or delete the file in a later layer, docker history can still expose values from earlier layers.
Unnecessary layer bloat
# BAD — 3 RUN commands = 3 layers, cache files stick around
RUN apt-get update
RUN apt-get install -y curl wget git
RUN rm -rf /var/lib/apt/lists/* # this delete is in a NEW layer, doesn't shrink image
# GOOD — single layer, cleanup in same RUN
RUN apt-get update && \
apt-get install -y --no-install-recommends curl wget git && \
rm -rf /var/lib/apt/lists/*Multi-Stage Builds: Discarding Heavy Layers
The best way to reduce final image size is multi-stage builds — you build in one image, copy only the output to a minimal final image:
# Build stage — has all the tools (large)
FROM golang:1.22 AS builder
WORKDIR /app
COPY . .
RUN go build -o server .
# Final stage — only the binary (tiny)
FROM scratch
COPY --from=builder /app/server /server
CMD ["/server"]The Go toolchain, source code, and intermediate files never appear in the final image. Only the compiled binary.
Quick Layer Inspection
# Dive tool — visual layer explorer
docker run --rm -it \
-v /var/run/docker.sock:/var/run/docker.sock \
wagoodman/dive myimage:latest
# Check image size breakdown
docker images --format "{{.Repository}}:{{.Tag}}\t{{.Size}}" | sort -k2 -hDive is the best tool for understanding exactly what each layer adds — it shows which files each layer creates, modifies, or deletes, and calculates the wasted space.
Layers are simple in concept but matter enormously for image size, build time, and security. Always ask: does this instruction create a layer that needs to exist in the final image?
Today I Fixed
Short real fixes from production — posted daily
Stay ahead of the curve
Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam — just practical engineering content.
Related Articles
Build an AI-Powered Dockerfile Security Scanner with Claude
Build a tool that scans Dockerfiles for security issues using Claude API — finds hardcoded secrets, root users, unscanned base images, and missing security best practices.
Build a DevSecOps Pipeline from Scratch (2026 Project Walkthrough)
A complete end-to-end DevSecOps pipeline with SAST, container scanning, secrets detection, DAST, and supply chain security using open-source tools.
Docker Complete Beginners Guide — Everything You Need to Know
What is Docker, why engineers use it, and how to get started with containers from scratch. A practical, no-fluff guide.