20.1.1.2 Image Container Contrast
A focused guide to Image Container Contrast, connecting core concepts with practical Docker and container operations.
Images and containers are the two central objects in Docker, and confusing them is one of the most common mistakes beginners make. They are related but distinctly different things: an image is static and immutable; a container is dynamic and mutable. Understanding this distinction precisely makes every other Docker concept easier to reason about.
The Image
A Docker image is a read-only, layered archive that contains everything needed to run an application: the filesystem snapshot (base OS files, application code, libraries, configuration), metadata (environment variables, working directory, entrypoint command), and history of how it was built.
Images are built from Dockerfiles or pulled from registries. Once built or pulled, the image does not change. Running 100 containers from the same image does not modify the image. The image is the template, the blueprint, the class definition.
Images are composed of layers stacked on top of each other. Each Dockerfile instruction that modifies the filesystem (RUN, COPY, ADD) creates a new layer. Layers below a given point are shared across all images and containers that use those layers, which makes storage efficient.
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest abc123def456 2 days ago 187MB
postgres 15 def456abc789 1 week ago 412MB
ubuntu 22.04 789abc012def 3 weeks ago 77.8MB
The Container
A Docker container is a running (or stopped) instance of an image. When a container is created, Docker adds a thin writable layer on top of the image's read-only layers. All filesystem changes the container makes — files created, modified, or deleted — are recorded in this writable layer. The underlying image layers are never modified.
The writable layer is private to the container instance. Two containers created from the same image start with identical filesystems but diverge as soon as they write anything.
docker ps -a
CONTAINER ID IMAGE STATUS NAMES
a1b2c3d4e5f6 nginx:latest Up 2 hours web_server
b2c3d4e5f6a1 nginx:latest Exited (0) old_web
c3d4e5f6a1b2 postgres:15 Up 1 hour database
The Layer Structure
The yellow layers are the image layers — read-only and shared between both containers. The green and blue layers are the per-container writable layers — private to each container and not shared.
One Image, Many Containers
A single image can be the basis for many simultaneously running containers, each with its own state:
docker run -d --name web1 nginx:latest
docker run -d --name web2 nginx:latest
docker run -d --name web3 nginx:latest
All three containers are running from the same nginx:latest image. If you modify a file inside web1, that change is visible only inside web1. The web2 and web3 containers, and the underlying nginx:latest image, are unaffected.
Mutability and Ephemeral State
An image is immutable: it cannot be changed after it is built. If you want to update the application, you build a new image with a new tag.
A container is mutable during its lifetime: files can be written and deleted in its writable layer. However, this state is ephemeral — when the container is removed with docker rm, the writable layer is permanently deleted. Any data written inside the container that was not stored in a Docker volume is lost.
This ephemeral nature is intentional. Containers are designed to be disposable and replaceable. Persistent data belongs in volumes, not in the container's writable layer.
Commands That Operate on Images vs. Containers
| Operation | Works on Images | Works on Containers |
|---|---|---|
docker images | List all | — |
docker pull | Download | — |
docker build | Create | — |
docker rmi | Remove | — |
docker ps | — | List running |
docker ps -a | — | List all |
docker run | (reads image) | Creates + starts |
docker stop | — | Stop |
docker start | — | Start stopped |
docker rm | — | Remove |
docker exec | — | Run command inside |
docker logs | — | View output |
docker inspect | Inspect | Inspect |
The docker inspect command works on both images and containers but returns different fields depending on the object type.
The Analogy
The image-to-container relationship is analogous to a class and an instance in object-oriented programming:
- The image is the class: the definition, the blueprint, the read-only template.
- The container is the instance: the running object created from the class, with its own mutable state.
Just as instantiating a class does not modify the class definition, running a container does not modify the image. And just as you can instantiate a class many times to create independent objects, you can create many containers from the same image, each running independently.