Volumes vs Bind Mounts
Comparison at a glance
Section titled “Comparison at a glance”| Property | Named Volume | Bind Mount |
|---|---|---|
| Path managed by | Docker | You |
| Host path required | No | Yes |
| Portability | High — works on any host | Low — path must exist on every host |
| Performance | Optimised by Docker storage driver | Direct host filesystem (fast on Linux, slower on macOS/Windows) |
| Backup | docker volume inspect + tar container | Copy files directly from the host path |
| Typical use case | Database files, app state, uploads | Source code, config files in development |
| Works in production | Yes | Rarely (depends on host layout) |
When to use each
Section titled “When to use each”Use named volumes when:
Section titled “Use named volumes when:”- You need data to survive container replacements (databases, object storage, cache).
- You are deploying to a remote host or CI/CD environment where the host path may differ.
- You want Docker to own the lifecycle of the storage.
Use bind mounts when:
Section titled “Use bind mounts when:”- You are developing locally and want live code reload without rebuilding the image.
- You need to inject a config file from the host into the container at runtime.
- You are running tools (linters, compilers) that produce output you want directly on the host.
Read-only mounts
Section titled “Read-only mounts”Both volume types support read-only mounts. The container can read data but cannot write to the mount target.
Named volume, read-only:
docker run --rm -v mydata:/app/data:ro alpine ls /app/dataBind mount, read-only:
docker run --rm -v $(pwd)/config:/etc/app/config:ro myimageWith --mount syntax (both types):
# Volumedocker run --rm --mount type=volume,source=mydata,target=/app/data,readonly myimage
# Binddocker run --rm --mount type=bind,source=$(pwd)/config,target=/etc/app/config,readonly myimageRead-only mounts are a security best practice when the container only needs to read the data — they prevent a compromised or buggy process from overwriting important files.
Hands-on practice
Section titled “Hands-on practice”The snippet below demonstrates both mount types side by side so you can observe the difference in a single session.
# --- Named volume ---
docker volume create compare-vol
# Write via container
docker run --rm -v compare-vol:/data alpine sh -c "echo 'from named volume' > /data/note.txt"
# Read from a new container (data persists)
docker run --rm -v compare-vol:/data alpine cat /data/note.txt
# --- Bind mount ---
mkdir -p /tmp/compare-bind
echo 'from bind mount' > /tmp/compare-bind/note.txt
# Read from container via bind mount
docker run --rm -v /tmp/compare-bind:/data alpine cat /data/note.txt
# --- Read-only mount ---
docker run --rm -v /tmp/compare-bind:/data:ro alpine sh -c "cat /data/note.txt && echo 'trying to write...' && echo 'blocked' > /data/note.txt || echo 'Write blocked as expected'"
# Clean up
docker volume rm compare-vol
rm -rf /tmp/compare-bind