Docker Image vs Container: Layers, Tags and Lifecycle Explained
Basics4 minInnovialabs editorial team
In short
A Docker image is an immutable template made of read-only layers; a container is a running instance of that image with its own thin writable layer on top, created, started, stopped and removed independently.
Image vs container in one sentence
An image is a template: a packaged filesystem plus metadata (default command, environment, exposed ports). A container is a process started from that template, with its own state. The relationship is like a class and its objects: one image, many containers.
- The image never changes once built.
- Each container gets a writable layer on top of the image where all its file changes go.
- Deleting a container deletes that writable layer, not the image.
Layers: how an image is built
Each instruction in a Dockerfile that changes the filesystem (RUN, COPY, ADD) produces a new read-only layer. Layers are stacked and shared between images.
FROM node:20-alpine # base image layers
WORKDIR /app
COPY package*.json ./ # layer: dependency manifests
RUN npm ci # layer: node_modules
COPY . . # layer: application code
CMD ["node", "server.js"] # metadata only, no new layer
Why this matters in practice:
- Caching: if only the application code changed, Docker rebuilds only the last
COPYlayer. That is why dependency files are copied before the rest of the code. - Storage: ten images built
FROMthe same base store that base only once. - Deleted files still weigh: removing a file in a later layer hides it but does not shrink earlier layers. Clean up in the same
RUNthat created the files, or use multi-stage builds.
See the layers of an image:
docker history myapp:1.4
docker image inspect myapp:1.4 --format '{{json .RootFS.Layers}}'
The writable layer
When a container starts, Docker adds a thin writable layer on top of the read-only image layers (copy-on-write). Any file the container modifies is copied up into this layer.
Consequences:
- Data written inside the container is lost when the container is removed. Use volumes or bind mounts for databases, uploads and anything that must survive.
- Two containers from the same image do not see each other's changes.
docker diff <container>shows what changed compared to the image.
Tags vs digests
A tag is a human-friendly, movable name: nginx:1.27, myapp:latest. The same tag can point to a different image tomorrow.
A digest is the content hash of an image: nginx@sha256:.... It is immutable: the same digest always means exactly the same bytes.
| Tag | Digest | |
|---|---|---|
| Example | myapp:1.4 | myapp@sha256:3f1a... |
| Can change | Yes, can be re-pushed | No |
| Good for | Humans, release names | Reproducible deploys, audits |
Practical rules:
- Avoid
latestin production; you cannot tell what is actually running. - Tag images with a version or commit SHA from CI.
- Pin by digest when reproducibility matters, for example in Kubernetes manifests for critical services.
docker images --digests
docker inspect --format '{{index .RepoDigests 0}}' myapp:1.4
Container lifecycle
A container goes through clear states: created → running → (paused) → exited → removed.
docker create --name web myapp:1.4 # created, not running
docker start web # running
docker stop web # SIGTERM, then SIGKILL after timeout: exited
docker start web # running again, same writable layer
docker rm web # removed, writable layer gone
docker run is simply create + start in one command. Add --rm to remove the container automatically when it exits.
Inspect each stage:
docker ps # running containers
docker ps -a # all containers, including exited
docker inspect web # state, mounts, network, exit code
docker logs web # stdout/stderr of the main process
docker image ls # images present locally
Common mistakes
- Treating containers as servers: installing packages inside a running container. The change disappears on recreation. Change the Dockerfile and rebuild instead.
- Storing data without volumes, then losing it after
docker rmor a redeploy. - Relying on
latestand getting a different image on another machine. - Piling up stopped containers and dangling images. Clean up regularly with
docker container pruneanddocker image prune, after checking what they will remove.