What's the difference between a Docker image and a container?

5 minbeginnerimagescontainersfundamentals

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.