Volumes and Data
A container's filesystem is disposable: delete the container, lose what it wrote. For databases, uploads, or anything you care about, store the data outside the container's writable layer. That's what volumes are for.
The rule
Treat containers as cattle, data as pets. The container can be destroyed and recreated freely; the data lives on.
Named volumes (the default choice)
docker volume create mydata
docker run -d --name db -v mydata:/var/lib/postgresql/data postgres:16
-v mydata:/var/lib/postgresql/data mounts the volume mydata at
that path inside the container. Postgres writes there thinking it's a
normal directory; Docker stores it in the volume. Delete the db
container and recreate it with the same -v — the data is still
there.
Check (verified):
docker volume ls
DRIVER VOLUME NAME
local mydata
docker volume inspect mydata --format '{{.Mountpoint}}'
/var/lib/docker/volumes/mydata/_data
That's where Docker keeps it on your machine. You rarely visit directly — manage volumes through Docker commands:
docker volume ls # list volumes
docker volume rm mydata # delete one (only when no container uses it)
Bind mounts (your files, live)
docker run -d --name web -v /home/paul/site:/usr/share/nginx/html nginx
A bind mount maps a directory on your machine into the container. Edit files on your host, the container sees them instantly. This is the development workflow: code on your machine, run in the container.
Careful: Bind mounts punch a hole between host and container.
Mounting / or your home directory into an untrusted container hands
it your files. Mount the narrowest directory that works.
Volumes vs. bind mounts
| Named volume | Bind mount | |
|---|---|---|
| Managed by | Docker | You (it's your path) |
| Best for | Databases, persistent app data | Development, config files |
| Survives container deletion | Yes | Yes (it's your disk) |
| Portable to another machine | No (stays on this host) | No |
The anonymous-volume trap
docker run -v /data postgres:16 # no name before the colon!
That creates an anonymous volume — it works, but good luck finding
it later (docker volume ls shows a hash). Always name your volumes.
Backing up a volume
Volumes live on the host, so back them up like anything else — but stop the container first (or use the app's own backup) so you don't copy a half-written database:
docker stop db
sudo tar -czf mydata-backup.tar.gz -C /var/lib/docker/volumes/mydata/_data .
docker start db
Next: Ports and Networking