Key idea
A container writes to a thin writable layer on top of its image. That layer belongs to that one container: it survives a stop and start, and it's deleted with the container. Updates replace containers, so anything written there is gone after the next deploy.
Where a container's writes go
An image is a stack of read-only layers (lesson 3.2.1). When a container starts, Docker adds one empty, writable layer on top. Every file your app creates, edits or deletes is recorded in that layer, never in the image.
docker diff lists what a container changed:
docker run --name notes-demo alpine:3.22 sh -c 'echo hi > /notes.txt; rm /etc/motd'
docker diff notes-demo
A /notes.txt
C /etc
D /etc/motd
A is added, C changed, D deleted. The image is untouched: a new container from alpine:3.22 still has /etc/motd and no /notes.txt. Remove this one with docker rm notes-demo.
Stop, restart, replace
What happens to the writable layer depends on what happens to the container:
- Stop and start the same container: the layer stays, with your files where you left them.
- Restart after a crash (lesson 3.3.2): it's the same container, so the layer stays.
- Remove it (
docker rm, or--rmwhen it exits): the layer is deleted with it. - Replace it with a new container, from the same image or a new one: the new container starts with a fresh, empty layer.
Replacing is the one that catches people, because it's how containers are updated. You don't patch a running container; you start a new one from a new image and remove the old one.
Running more copies works the same way. Each copy gets its own empty layer, so copies can't see each other's files either.
What belongs there
The writable layer is fine for scratch work: temporary files, caches your app can rebuild, a file being processed before it's uploaded. Treat it as disposable.
Anything you need to keep, such as uploads, a SQLite file or generated reports, needs a home outside the container:
- a volume, storage Docker keeps outside any container and mounts into one (next lesson);
- a database running as its own service;
- object storage, for files your app sends over HTTP.
Check yourself