Layered, read-only filesystems that get stacked to build the environment a container runs in.
Each instruction in a Dockerfile typically produces its own layer, and layers are cached and reused across builds and even across different images that share a common ancestry — which is exactly why instruction order in a Dockerfile matters for cache efficiency, and why two images sharing a base layer don't duplicate that layer's storage on disk.
A tag (like myapp:1.2) is a mutable pointer that can be reassigned to point at a different image later, while a digest is an immutable content hash that always refers to the exact same bytes — a real distinction when reproducibility matters. Multi-stage builds let a Dockerfile use one stage to compile or build an app (with all its build tools) and a separate, minimal final stage that only copies over the compiled output, which is what keeps a production image from shipping an entire build toolchain it no longer needs.
What you'll walk away knowing