What's the difference between a Docker image and a container?
Quick Answer
An image is a read-only, immutable template — a packaged set of filesystem layers plus metadata (what command to run, what ports to expose) — that never changes once built. A container is a running (or stopped) instance created from an image, with its own thin writable layer on top for any runtime changes, plus its own isolated process, network, and filesystem view. One image can be used to start many independent containers, each isolated from the others, the same way a class and its instances relate to each other in object-oriented programming.
Detailed Answer
The image: a read-only template
docker build -t myapp:1.0 .
docker images
# REPOSITORY TAG IMAGE ID SIZE
# myapp 1.0 a1b2c3d4e5f6 180MB
An image is the packaged, immutable result of a build — a stack of filesystem layers (see the layer caching question) plus metadata describing how a container from it should run (its default command, exposed ports, environment defaults). An image itself is never "running" — it's inert, stored data, the same way a class definition or a compiled binary on disk isn't itself "executing."
The container: a running instance, with its own writable layer
docker run -d --name web1 myapp:1.0
docker run -d --name web2 myapp:1.0
docker ps
# CONTAINER ID IMAGE NAMES
# 7f8e9d0c1b2a myapp:1.0 web1
# 3c4d5e6f7a8b myapp:1.0 web2
Each docker run from the same image creates a genuinely separate, independent container — its own process namespace, its own network namespace and IP, and its own thin writable layer stacked on top of the image's read-only layers. Any file changes a container makes at runtime (writing a log file, a temp file) go into that container's own writable layer. This layer is completely invisible to, and independent of, any other container started from the same image. It is lost when that specific container is removed.
The class/instance analogy
Image ≈ a class definition (myapp:1.0 — describes what to run and how)
Container ≈ an instance of that class (web1, web2 — each independently running,
independently stateful, independently
destroyable, without affecting the others
or the original image)
Starting web2 doesn't consume or modify myapp:1.0 in any way — the image stays exactly as it was, ready to spawn any number of further independent containers.
What happens to a container's writable-layer data
docker stop web1
docker start web1 # any files written to web1's writable layer are still there
docker rm web1 # NOW that writable layer, and everything in it, is gone permanently
Stopping and restarting a container preserves its writable layer's contents. Removing a container discards it entirely. This is exactly why anything meant to persist beyond a single container's lifetime, such as real application data, belongs in a volume rather than the container's own writable layer (see the storage topic).
Why this distinction is foundational to everything else in Docker
Nearly every other Docker concept builds directly on this image/container split. Layer caching and multi-stage builds are about how images are constructed efficiently. Volumes and bind mounts exist specifically because a container's own writable layer is ephemeral and tied to that one container. Registries exist to distribute images (not containers), so that any number of independent containers can be started from the same shared, versioned artifact across many different machines.