Persisting data with volumes
The problem: a container's filesystem doesn't survive the container
Recall from the images-vs-containers concept that each container has its own isolated filesystem, separate from the image and from other containers. What wasn’t shown there: that filesystem is also ephemeral — removing a container removes everything written inside it, including data you actually wanted to keep.
Start a container running a small script that appends a line to
/data/log.txt each time it’s called, call it a few times, then stop
and remove the container:
click Run to see this pane's outputA brand-new container, from the exact same image, has no memory of the
previous containers’ writes — /data/log.txt never existed as far as
this new container is concerned, because it was never part of the
image, only ever written into now-deleted containers’ own throwaway
filesystems.
Volumes: storage that outlives a container
A volume is storage that exists independently of any one container —
you attach it to a container with -v, and it survives that container
being stopped and removed, ready to be attached to a different
container later:
click Run to see this pane's outputmy-data:/data means “mount the volume named my-data at /data
inside the container.” The first container wrote to /data/log.txt
inside that volume; the second container — a completely fresh one, with
no relationship to the first beyond sharing the same volume — reads it
back successfully, because the volume itself was never deleted along
with the first container.
Named volumes vs. bind mounts
docker volume create my-data above makes a named volume — storage
Docker manages for you, in a location you don’t need to know or care
about. The alternative is a bind mount: pointing directly at a real
path on your own machine instead:
docker run -v $(pwd)/local-data:/data my-app --onceHere, /data inside the container is literally local-data in your
current directory on the host — editable directly from outside the
container too, which is convenient for development (editing code live
without rebuilding) but less appropriate for something like a
database’s actual data files, where a named volume, managed entirely by
Docker, is the more standard choice.
Why does data written inside a container disappear once that container is removed, even though the image it came from still exists?