How do volume drivers extend Docker's storage capabilities?
Quick Answer
A volume driver is a pluggable backend that determines where and how a named volume's actual data is stored — the default local driver simply uses a directory on the host's own disk, but third-party and cloud-provider volume drivers can back a volume with NFS, cloud block/object storage, or other distributed storage systems, all while the container itself still just references the volume by name with the same -v/--mount syntax. This lets the same container configuration work with dramatically different underlying storage infrastructure, without the application or its Docker configuration needing to know or care which one is actually in use.
Detailed Answer
The default: the local driver
docker volume create my-data
docker volume inspect my-data
# "Driver": "local"
# "Mountpoint": "/var/lib/docker/volumes/my-data/_data"
Without specifying a driver, Docker uses the built-in local driver, which simply creates and manages a directory on the host machine's own disk. This is fine for single-host setups, but it means the volume's data is physically tied to that one specific host — if the container needs to move to a different machine, the volume (and its data) doesn't automatically come along.
Using an alternative volume driver
docker volume create --driver local \
--opt type=nfs \
--opt o=addr=192.168.1.100,rw \
--opt device=:/exported/path \
my-nfs-volume
docker run -d -v my-nfs-volume:/app/data myapp:1.0
This example uses the local driver's own built-in NFS mount option support, backing the "volume" with a remote NFS share instead of purely local disk. The container's own configuration (-v my-nfs-volume:/app/data) looks identical to using a plain local volume. Only the volume's own creation-time definition differs.
Third-party volume driver plugins extend this further, supporting cloud block storage services, distributed storage systems (Ceph, GlusterFS), and other backends. Each implements Docker's volume plugin API, so that, from the container's perspective, using them requires no different syntax than using any other named volume.
Why this abstraction matters
Container's perspective: -v my-data:/app/data (identical, regardless of backend)
Actual backend, depending on the driver used:
- local disk (default "local" driver)
- NFS share
- Cloud block storage (via a cloud-specific driver)
- A distributed storage system
This mirrors exactly the same abstraction philosophy behind Kubernetes's StorageClasses and the CSI (Container Storage Interface; see that stack's question). Application/container configuration references storage in an abstract, backend-agnostic way, while a pluggable driver layer handles the actual, potentially very different, underlying implementation. The benefit is the same in both ecosystems: you can change or upgrade the underlying storage infrastructure without needing to rewrite every container's configuration that references it.
When you'd actually reach for a non-default driver
- Multi-host setups without a full orchestrator — if you're running plain Docker (not Swarm or Kubernetes) across multiple hosts, and need a container's data to be accessible regardless of which specific host it happens to run on, a network-backed volume driver (NFS, a distributed storage plugin) solves this. The default
localdriver's host-tied storage would not. - Cloud-native storage integration — using a cloud provider's own volume driver plugin to back Docker volumes directly with that provider's managed block/file storage service, gaining that service's own durability, snapshotting, and replication features.
For simple, single-host Docker deployments, the default local driver remains entirely sufficient and requires no extra configuration at all.