The core idea
Everything a container writes, unless you say otherwise, goes into its writable layer. That layer belongs to the
container: it survives stop and start, and it's deleted with docker rm. Containers are meant to be thrown away
and replaced, so anything you want to keep has to live outside the container.
Watch data disappear
$ docker run -d --name scratch alpine sleep 1000$ docker exec scratch sh -c 'echo "important" > /data.txt; dd if=/dev/zero of=/big bs=1M count=50'$ docker ps -s --filter name=scratch --format 'table {{.Names}}\t{{.Size}}'NAMES SIZEscratch 52.4MB (virtual 61.8MB)$ docker diff scratchA /bigA /data.txt$ docker stop scratch && docker start scratch$ docker exec scratch cat /data.txtimportant$ docker rm -f scratch$ docker run --rm alpine cat /data.txtcat: can't open '/data.txt': No such file or directory
docker ps -s shows the writable layer's size (52.4 MB) and, in brackets, that plus the image underneath. A stop and
start keeps the file. Removing the container deletes it, and a new container from the same image starts clean.
That's fine for a cache. It's a disaster for a database, which is exactly what happens if you run Postgres and later recreate the container to upgrade it.
Why not just keep the container forever?
Because you can't, in practice:
- Deploying means replacing. A new image version means a new container.
- Writable layers are slow for heavy writes. Changing a file from the image first copies it into the writable layer (copy-on-write), and the storage driver adds overhead that databases feel.
- Writable layers are hard to back up, move to another server or share between containers.
Three places data can live
| Mount | Lives in | Use it for | Lesson |
|---|---|---|---|
| Volume | storage Docker manages (/var/lib/docker/volumes/…) | databases, uploads: data the app owns | 04.02 Volumes |
| Bind mount | a folder you choose on the host | source code in development, config files | 04.03 Bind mounts |
| tmpfs | memory, never disk | scratch space, secrets that must never touch disk | 04.04 tmpfs mounts |
You run Postgres in a container with no mounts, add data, then docker stop and docker start it. Then you upgrade by docker rm and docker run with the newer image. What happens to the data?
That quiz is the next lesson's motivation: name your volumes.
Run the commands above. Then check docker ps -s on a running notes API: its writable layer should be tiny, because it doesn't write files. That's the goal for most app containers.
STUCK? ▸
If the file is still there after docker rm, check you started a new container with docker run rather than docker start on the old one.
Recap
Interview questions
Where does data written inside a container go, and what happens to it when the container is removed?