An image is a read-only, static template containing instructions for creating a container, while a container is a runnable instance of that image, adding a writable layer on top for runtime modifications.
The fundamental relationship between an image and a container can be understood by comparing them to a class and an object in object-oriented programming. An image is the class—a static blueprint that defines what the application should look like. A container is the object—a running instance created from that blueprint that can be started, stopped, moved, and deleted. Images are immutable and can be shared, while containers are ephemeral and have a lifecycle.
Immutability vs mutability: Images are completely read-only and cannot be changed after creation. Containers add a thin writable layer on top of the image layers, allowing runtime modifications like writing logs, creating temporary files, or updating application state.
State: An image is a static artifact that can be stored in a registry and versioned. A container is a dynamic runtime environment that has a lifecycle (created, running, paused, stopped, deleted).
Storage: Images are stored in layers and shared across multiple containers to save disk space. Each container adds its own thin writable layer, which is why creating many containers from the same image consumes minimal additional space.
Persistence: Images persist indefinitely until explicitly deleted. Containers are ephemeral by nature—when deleted, all changes in the writable layer are lost unless volumes were used to persist data.
Names: Images are identified by repository and tag (e.g., ubuntu:22.04). Containers have unique IDs and can optionally be assigned human-readable names.
The layering mechanism is crucial to understanding this relationship. A Docker image consists of multiple read-only layers stacked on top of each other. When you create a container, Docker adds a new thin, writable layer on top of these existing layers—this is often called the container layer. All changes made to the container during its lifetime (creating files, modifying configuration, installing packages) are written to this writable layer. When the container is deleted, this writable layer is discarded, but the underlying image layers remain intact and unchanged .
This separation enables powerful workflows. You can run multiple containers from the same image, each with its own isolated writable layer. For example, you could run five separate nginx containers from the same image, each serving different content because their writable layers contain different website files. You can also commit a container's changes to create a new image using docker commit, which saves the current state of the writable layer as a new image layer, though this practice is generally discouraged in favor of using Dockerfiles for repeatable builds .