DockerBeginner 12 min Lesson 2 of 10

Images

What an image actually contains, how layers and caching work, why tags matter, and how to keep images small.

Docker · Lesson 2 of 10
0/10 done(0%)

What is it? #

An image is a read-only template containing a filesystem and the metadata needed to start a container from it.

Images are built in layers. Each instruction in a Dockerfile produces a layer, layers are cached, and images sharing a base share those layers on disk and over the network.

Tags name a version of an image. latest is not a special version — it is just the default tag, and relying on it means you do not know what you are running.

Size matters more than people expect. A 1.2 GB image is slower to build, slower to pull, slower to deploy and contains more software that could be vulnerable.

Think of it like this #

A recipe that produces a sealed meal kit. The kit is identical every time it is made from the same recipe, and kits sharing ingredients store them once.

The label on the kit is the tag. A label reading "newest" tells you nothing about what is inside.

Simple example #

Two applications both based on python:3.12-slim. The base layers are stored once, and each image adds only its own dependencies and code on top.

Code #

BASH
docker pull python:3.12-slim
docker images                      # what is stored locally, with sizes
docker history python:3.12-slim    # the layers and what created them
docker inspect python:3.12-slim    # full metadata

docker rmi <image>                 # remove one
docker image prune -a              # remove everything unused (reclaims a lot)
TEXT
Layers and caching

FROM python:3.12-slim          ← layer 1 (shared with every other image using it)
WORKDIR /app                   ← metadata, no real layer
COPY requirements.txt .        ← layer 2  (changes only when requirements change)
RUN pip install -r requirements.txt   ← layer 3  (expensive; cached if layer 2 is unchanged)
COPY . .                       ← layer 4  (changes on every code edit)

Docker rebuilds from the first changed layer onwards. Copying
requirements before the code means a code change does not reinstall
dependencies — a rebuild of seconds instead of minutes.
TEXT
Tags

python:3.12.7-slim-bookworm    exact: reproducible, what production should use
python:3.12-slim               minor updates allowed: reasonable for development
python:3-slim                  any 3.x: too loose
python:latest                  whatever was pushed last: not a version at all

Digests are absolute:
  python@sha256:9c1c...        this exact image, forever
TEXT
Size, for the same application

python:3.12          ~1.0 GB     full distribution, compilers included
python:3.12-slim     ~150 MB     minimal Debian, the usual choice
python:3.12-alpine   ~60 MB      musl libc: smaller, but some wheels
                                 must compile from source, and subtle
                                 differences can appear at runtime
distroless           ~50 MB      no shell, no package manager: most secure,
                                 hardest to debug

Slim is the pragmatic default. Alpine is worth it when size genuinely
matters and you have tested your dependencies against it.

How it works #

Each layer is a set of filesystem changes. Layers are immutable and content-addressed, so two images built from the same base reference the same stored layers rather than duplicating them.

The build cache works layer by layer. If an instruction and its inputs are unchanged, the cached layer is reused; once one layer changes, every layer after it is rebuilt.

That is why instruction order matters so much. Copying dependency files and installing before copying source code means everyday code changes reuse the expensive install layer.

Layers are additive only. Deleting a file in a later layer hides it but does not remove it from the image, which is why secrets copied in and later deleted are still recoverable from the image history.

Tags are mutable pointers. The same tag can point at a different image tomorrow, which is precisely why production should pin an exact version or a digest.

Smaller base images contain fewer packages, which means a smaller attack surface and fewer vulnerabilities reported by scanners, as well as faster pulls.

Alpine's smaller size comes from musl libc rather than glibc. Most software works, some Python wheels must be compiled instead of downloaded, and occasional runtime differences appear — which is why testing it rather than assuming is the right approach.

Real-world use #

Registries store images: Docker Hub, GitHub Container Registry, and cloud provider registries. Private registries hold your own application images.

Image size affects deployment speed directly. Pulling 1 GB to five machines on every deploy is slow; pulling 100 MB is not.

Vulnerability scanning is standard in CI. A minimal base image produces dramatically shorter reports, mostly because it contains less software.

Pinning by digest is the strongest form of reproducibility, and it is what supply-chain-conscious teams use for base images.

The layer caching behaviour is the single biggest factor in build speed, which the Dockerfile lesson covers in practical detail.

Common mistakes #

  • Using the latest tag in production, so nobody knows what is deployed.
  • Copying source code before installing dependencies, destroying the cache.
  • Assuming a deleted file is removed from the image — earlier layers still contain it.
  • Choosing Alpine without testing, then debugging obscure library differences.
  • Never pruning unused images until the disk is full.

Practice #

Pull the full and slim variants of a language image and compare their sizes. Inspect the layer history of one. Then build a small image twice, changing only source code, and observe which layers are rebuilt and which come from cache.

Quick quiz

  1. 1. What is a Docker image?

  2. 2. Why copy dependency files before source code?

  3. 3. What does the `latest` tag mean?

  4. 4. Does deleting a file in a later layer remove it from the image?

  5. 5. What is the practical default base image choice?

Summary

  • An image is a layered, read-only filesystem template.
  • Layer caching rewards putting stable instructions before changing ones.
  • Deleted files remain in earlier layers — never add secrets.
  • Pin exact versions or digests in production; `latest` is not a version.
  • Slim base images are the pragmatic default for size and safety.