Topic 3.1
Why Containers Need Volumes
In one line
Delete a database container without a volume, and every row you ever inserted is gone forever. Volumes exist to make data outlive the container that produced it.
Think of it like this
A hotel room (the container) versus your own personal storage unit (a volume). You can check out of the hotel room, and the next guest gets a completely reset room — nothing of yours remains. Your storage unit, however, is a SEPARATE thing you keep across as many hotel stays as you like; it's not tied to any one room's lifecycle.
Key ideas
- 01
By default, ALL data written inside a running container lives in that container's own writable layer, which is deleted the instant the container is removed (
docker rm) — this is by design (Topic 1.1) but is a serious problem the moment you have data you actually need to keep, like a database's files. - 02
A VOLUME is storage that exists INDEPENDENTLY of any single container's lifecycle — it's managed by Docker, lives on the host filesystem in a location Docker controls, and can be attached to a container, detached, and reattached to a DIFFERENT container later, all while the data itself persists unchanged.
- 03
The core mental model: separate your container (compute, disposable, replaceable) from your data (storage, precious, persistent). A well-designed containerized app can be deleted and recreated from its image at any time with zero data loss, because the actual data lives in a volume outside the container entirely.
- 04
Without a volume, restarting a database container is fine (same container, same writable layer) — but recreating it (removing and running a fresh one, which happens constantly in real deployments for upgrades) wipes everything. This is the exact failure mode volumes prevent.
- 05
Three ways to persist data in Docker, briefly: named volumes (Docker-managed, the recommended default — Topic 3.2), bind mounts (you point directly at a folder on your host — Topic 3.3), and tmpfs mounts (in-memory only, never touches disk, gone on container stop — used for temporary sensitive data).
In your stack
- →
The most common real scenario: running a PostgreSQL container for local Spring Boot development. Without a volume, every time you
docker-compose downand backup(very common during development), your entire local database resets to empty — with a volume, your test data survives across as many restarts as you like.
Code & diagrams
Prove the data loss to yourself once — you'll never forget it after.
# Run Postgres with NO volume
docker run -d --name pg-no-volume -e POSTGRES_PASSWORD=secret postgres:16
# Connect and insert some data
docker exec -it pg-no-volume psql -U postgres -c "CREATE TABLE test (id int); INSERT INTO test VALUES (1);"
# Remove the container (simulating an upgrade, a crash recovery, anything)
docker rm -f pg-no-volume
# Start a "fresh" container from the same image
docker run -d --name pg-no-volume -e POSTGRES_PASSWORD=secret postgres:16
# The table is GONE — this container has no memory of the last one
docker exec -it pg-no-volume psql -U postgres -c "SELECT * FROM test;"
# ERROR: relation "test" does not existThe container is disposable. The volume is what actually needs to survive.
Explain it without notes
Why does restarting the SAME container (docker stop then docker start) preserve data, but removing and recreating it (docker rm then docker run) lose everything, if there's no volume involved?
Explain the 'compute vs storage' mental model in your own words, using any real app as an example.
Practice
Reproduce this topic's 'the-problem.sh' exercise yourself, end to end, and confirm the data loss firsthand.
Before reading Topic 3.2, guess: what command-line flag do you think would fix this problem, based on everything you know about Docker so far?
Trade-offs
- ↔
Not every container needs a volume — a purely stateless web server or a short-lived batch job that reads input and writes a result elsewhere (like to a database that DOES have a volume) is perfectly fine without one; add volumes deliberately for data you actually need to survive, not as a reflexive default on every container.
Done when you can
I've personally reproduced the data-loss problem this topic describes.
I can explain the 'compute vs storage' separation in my own words.