Skip to main content

Docker

image vs container

Short answer

An image is a read-only template. A container is a running instance of one, with a writable layer on top that disappears when the container is removed.

In simple terms

The distinction sounds pedantic until data goes missing, at which point it becomes the whole story.

An image is built once and never changes. A container is created from an image and gets a thin writable layer of its own, stacked on top of the image's read-only layers. Anything the container writes goes into that layer, and that layer belongs to the container, not the image.

So two containers from the same image start identical and immediately diverge. And when a container is removed, its writable layer is removed with it. Nothing about the image changed, which is why rebuilding or re-running gets you back to the original state — and why the file you carefully wrote is gone.

What actually happens

An image is a stack of filesystem layers plus a configuration object, identified by the digest of its content. Layers are shared between images, which is why pulling a second image based on the same base is fast.

Creating a container adds a writable layer using a union filesystem, usually overlayfs. Reads fall through to the layers below; writes go into the top layer. Modifying an existing file triggers copy-up: the whole file is copied into the writable layer first, which is why writing to a large file in a container can be surprisingly slow the first time.

The consequence for secrets is worth stating separately, because it catches people out. A file added in one image layer stays in that layer even if a later layer deletes it. Deleting a copied credential does not remove it — anyone with the image can recover it from the earlier layer.

The divergence, demonstrated

docker run --name a -d myapp
docker run --name b -d myapp     # same image, separate writable layers

docker exec a sh -c 'echo hello > /tmp/note'
docker exec b cat /tmp/note      # No such file — b never saw it

docker rm -f a
docker run --name a -d myapp
docker exec a cat /tmp/note      # Still gone. The layer went with the container.

For anything that must outlive the container, mount a volume. That is not an optimisation, it is the only mechanism — a writable layer is explicitly temporary.

◑ The mistake this causes

Treating the container's filesystem as somewhere data can live.

Why people do it It behaves exactly like a normal filesystem right up until the container is replaced, and containers get replaced constantly — on every deploy, every restart, every reschedule.

What you see Uploaded files, SQLite databases or generated content vanish after a deploy. Nothing errors and nothing is logged, because from the container's point of view nothing went wrong: a brand-new container simply has a brand-new empty writable layer.

How it shows up in production

The same misunderstanding runs in the other direction with secrets, and there it is permanent rather than merely inconvenient.

A `.env` file gets copied into an image during a build and deleted in a later step. The build output looks clean and the running container has no such file. But the layer created by the copy still contains it, the image was pushed to a registry, and anybody who can pull it can extract the secret with `docker history` and a layer dump. Rebuilding does not help, because the published image already exists. Only revoking the credential does.

How to tell which one you are hitting

Did the data survive a restart but not a replacement?
`docker restart` keeps the same container and its writable layer. `docker rm` then `docker run` creates a new one. If data survives the first and not the second, it is in the writable layer and needs a volume.
Is a deleted file really gone from the image?
Run `docker history --no-trunc <image>` and look for the step that added it. If a layer added it, it is still there regardless of what a later layer did.
How this gets asked in an interview

Usually phrased as “What is the difference between an image and a container?”

What a strong answer contains Template versus running instance, then go straight to the writable layer and what happens to it. Mentioning copy-up, layer sharing, or the fact that deleting a file does not remove it from an earlier layer takes the answer beyond the definition.

The follow-up “Where would you put data that has to persist?” leads to volumes, and then to how that changes again under Kubernetes with PersistentVolumeClaims.

What comes next

Did this get you to an answer?

No text box on purpose — please do not paste production logs anywhere