Data and networking
Choose volumes or bind mounts
Use named volumes for Docker-managed data and bind mounts when the host must directly provide or edit files.
Both volumes and bind mounts put external storage at a path inside the container. They look similar in a command, but they solve different problems.
A named volume is storage Docker manages. You give it a name; Docker decides where it lives. A bind mount is a directory on your machine that you map into the container by its full path. You decide where it lives.
When to use each
Volumes for data the app owns and nobody edits by hand: a database directory, uploaded files, a cache. Docker handles the location, so the same command works on any machine.
Bind mounts for files a human edits: your source code during development, a config file you want to tweak without rebuilding. The container sees your edits immediately.
Two containers, one volume
Write a file into a volume from one container, then read it from another:
docker run --rm -v notes-data:/data alpine sh -c "echo hello > /data/note.txt"
docker run --rm -v notes-data:/data alpine cat /data/note.txt
The second command prints hello. Two containers, both gone thanks to --rm, and the file survived in the notes-data volume.
Now mount the current directory into a container, read-only:
docker run --rm --mount type=bind,src="$PWD",dst=/work,readonly alpine ls /work
You’ll see your project files listed. That’s a bind mount: src is a real host path, dst is where it appears in the container. --mount is the longer syntax. -v works too, but --mount is more explicit and I prefer it for bind mounts.
A mount hides what’s underneath
If the image already has files at the mount path, the mount covers them. Mount your empty local folder over /app and the code the image copied there disappears from view. This is a frequent “why is my app not found” moment.
What bind mounts cost you
A bind mount inherits everything from the host path: whether it exists, its permissions, its contents. It ties the container to one machine, because /Users/flavio/notes-api doesn’t exist on your server. And a writable bind mount lets the container modify your files. That’s the point in development. Everywhere else, add readonly, and a container can’t overwrite something it shouldn’t.
Volumes are more portable, but they don’t free you from thinking about ownership (which user in the container writes to them) or backups.
The questions to ask
Before picking one, ask: who owns this data? Does a human need to edit it directly? Should the container be able to write it? How would I restore it? Volumes and bind mounts are not two spellings of the same thing, and those four questions almost always pick the right one for you.
Try this: persist one file in a volume, then mount the project directory read-only into another container and try to create a file there. You’ll get Read-only file system.
Lesson completed