Docker Bind Mounts or Volumes? A Practical Choice
Choose between Docker bind mounts and named volumes by ownership, portability, backup needs, and failure modes.

Photo: Unsplash.
Both bind mounts and named volumes put persistent data outside a container’s writable layer. The important difference is who owns the path.
A bind mount maps a path you choose:
services:
site:
volumes:
- ./config/nginx.conf:/etc/nginx/nginx.conf:ro
This is ideal when the host and container should both see a file: source code during development, checked-in configuration, or generated artifacts. The trade-off is coupling. Move the project to a host with a different directory layout or permissions and the mount may fail.
A named volume is managed by Docker:
services:
db:
image: postgres:17
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
It is usually the calmer choice for database state and application data that only containers need. Inspect it with docker volume inspect postgres_data; do not build procedures around its internal path under Docker’s data directory.
My rule is simple:
- Use a bind mount when the host intentionally owns and edits the file.
- Use a named volume when the service owns the data.
- Use
:rowhenever the container only needs to read a bind mount. - Test the backup and restore process independently of either choice.
One trap is docker compose down -v: the -v explicitly removes named volumes declared by the project. That may be desirable in a disposable development stack and disastrous around production data. Read the command before pressing Enter.
A volume is persistence, not a backup. Export data using the database’s supported tools or a tested filesystem procedure, store it elsewhere, and practice restoring it.
