Volumes and data
Containers are disposable; your data is not. Volumes and bind mounts keep files outside the container, so they survive removal, upgrades and rebuilds.
? What do the diagram colours mean
key idea / Docker itselfcontainer / good pathhost / watch outproblem / blockedneutral
Where data can live
A container’s own files live in its writable layer (chapter 2). That layer is deleted with the container. To keep data, mount storage that lives outside it.
| Named volume | Bind mount | tmpfs | |
|---|---|---|---|
| Flag | -v pgdata:/data | -v "$PWD/src:/app/src" | --tmpfs /tmp/cache |
| Lives in | Docker’s storage area | any host path you choose | memory |
Survives docker rm | yes | yes, it is your folder | no |
| Use it for | databases and app state | source code while developing, config files | secrets and scratch files that must not hit disk |
The rule of thumb: volumes for data Docker should own, bind mounts for files you want to edit. A bind mount depends on the host’s folder layout; a named volume works the same on every machine.
Data that outlives the container
-v and --mount
Both flags do the same job. -v is short; --mount spells every part out and fails loudly on a typo instead of silently creating an empty volume.
$ docker run -d --name db -v pgdata:/var/lib/postgresql/data postgres:16
$ docker run -d --name db --mount type=volume,src=pgdata,dst=/var/lib/postgresql/data postgres:16
$ docker run -d -v "$PWD/nginx.conf:/etc/nginx/nginx.conf:ro" nginx:1.27 # :ro = read-onlyIf the first part of -v starts with / or ./ it is a bind mount; otherwise it is a volume name. -v data:/x and -v ./data:/x are very different things.
Managing volumes
| Command | Does |
|---|---|
docker volume ls | lists volumes |
docker volume inspect pgdata | shows where it lives and when it was created |
docker volume rm pgdata | deletes it, and its data, for good |
docker volume prune | deletes every volume no container uses. Read the list first. |
To back a volume up, mount it next to a host folder in a throwaway container and tar it:
$ docker run --rm -v pgdata:/data:ro -v "$PWD:/backup" alpine:3.20 tar czf /backup/pgdata.tgz -C /data .Try it yourself
-
Step 1 · Write into a named volume
docker runcreatesnotesthe first time it is used.$ docker run --rm -v notes:/data alpine:3.20 sh -c 'echo first note > /data/today.txt' $ docker volume ls DRIVER VOLUME NAME local notes -
Step 2 · A brand-new container sees the same file
The first container is already gone (
--rm). The data was never in it.$ docker run --rm -v notes:/data alpine:3.20 cat /data/today.txt first note -
Step 3 · Without a volume, the file dies with the container
$ docker run --name temp alpine:3.20 sh -c 'echo lost > /today.txt' $ docker rm temp $ docker run --rm alpine:3.20 cat /today.txt cat: can't open '/today.txt': No such file or directory -
Step 4 · A bind mount shows host edits live
Change the file on the host; the container sees it immediately, with no rebuild.
$ mkdir site && echo '<h1>v1</h1>' > site/index.html $ docker run -d --name web --rm -p 8080:80 -v "$PWD/site:/usr/share/nginx/html:ro" nginx:1.27 $ curl -s localhost:8080 <h1>v1</h1> $ echo '<h1>v2</h1>' > site/index.html $ curl -s localhost:8080 <h1>v2</h1> $ docker stop web -
Step 5 · Clean up
$ docker volume rm notes notes
/app, which hides the node_modules the image installed. A mount covers everything at that path. Mount only the source folder, or add an anonymous volume for /app/node_modules.Recap
- The writable layer is deleted with the container. Anything you need later goes in a mount.
- Named volumes are managed by Docker and survive
docker rm: use them for databases. - Bind mounts map a host folder you choose: use them for code and config you edit.
tmpfslives in memory only. Add:roto mount anything read-only.docker volume rmandprunedelete data permanently.
Quick check
You upgrade Postgres with docker rm db and a new container from a newer image. When is the data still there?
Show answer
Answer: Only if the data directory was on a volume or bind mount.
The writable layer is deleted with the container. Data in a named volume or bind mount survives and can be mounted by the new container.
You want to edit code on your laptop and see the change in the container immediately. Which mount?
Show answer
Answer: A bind mount of your source folder.
A bind mount maps your host folder into the container, so both see the same files.
Docker volumes: common questions
What is the difference between a Docker volume and a bind mount?
A named volume is storage that Docker manages and is the same on every machine. A bind mount maps a host folder you choose into the container, which suits code and config you edit.
Does docker rm delete volumes?
No. docker rm deletes the container and its writable layer. Named volumes stay until you run docker volume rm, docker volume prune or docker compose down -v.