Master Docker Data Persistence: Volumes, Bind Mounts, and Tmpfs Explained
This article explains why storing data in a container layer is problematic and details Docker's three persistent storage options—volumes, bind mounts, and tmpfs—along with their usage commands, scenarios, and advanced features such as bind propagation, SELinux labels, and volume drivers.
Data stored in a container layer is not persistent, is hard for host processes to access, and incurs performance overhead due to I/O passing through the storage driver.
Data disappears when the container is removed.
Host processes cannot easily read the data.
I/O performance degrades because of an extra storage layer.
Docker offers three ways to persist data:
volumes : Managed by Docker in a directory on the host filesystem (e.g.,
/var/lib/docker/volumes/). Recommended for most persistent data.
bind mount : Any location on the host filesystem; host processes can modify the data.
tmpfs mount (Linux only): Stores data in memory, not on disk, suitable for temporary or sensitive data.
volumes
If not explicitly created, a volume is created on first mount and remains after the container stops; it is removed only when explicitly deleted.
When mounting an empty volume over a directory with existing files, Docker copies those files into the volume; mounting a non‑empty volume hides the container’s original files.
Usage
Create:
docker volume createRemove a volume:
docker volume rm <volume_name>Remove unused volumes:
docker volume pruneList volumes:
docker volume lsInspect a volume:
docker volume inspect <volume_name>Mount to a container:
-vor
--volume; for Docker 17.06+ the preferred syntax is
--mount(same as bind mount).
Mount options include keys such as
type(bind, volume, tmpfs),
source/
src,
destination/
dst/
target, and optional parameters separated by commas (e.g.,
rofor read‑only).
When using docker service create , only --mount is supported; -v and --volume are not.
Scenarios
Sharing data between multiple running containers.
Decoupling container runtime configuration from the host filesystem.
Backup, restore, or migration of data between Docker hosts.
bind mount
A host file or directory is referenced by its full path; the target path on the host does not need to exist beforehand.
If a directory is mounted over an existing directory in the container, the container’s original files become hidden. When the host path does not exist, Docker creates it if
-vor
--volumeis used;
--mountwill error.
Usage
Mount to a container with
-vor
--volume; for Docker 17.06+ prefer
--mount.
-v/
--volume: three fields separated by ‘:’ (source, target, options).
--mount: comma‑separated key=value pairs, e.g.,
type=bind,source=/host/path,target=/container/path,readonly,bind-propagation=rslave.
Scenarios
Generally, use volumes when possible.
Sharing configuration files (e.g., mounting
/etc/resolv.conffor DNS).
Sharing source code or build artifacts.
Ensuring host and container directory structures match.
bind propagation
Default is rprivate ; only configurable on Linux for bind mounts and rarely needed.
Example: mounting
/target/twice in a container shows how changes in one mount point appear in the other when propagation is set to
rslave:
<code>docker run -d \
-it \
--name devtest \
--mount type=bind,source="$(pwd)"/target,target=/app \
--mount type=bind,source="$(pwd)"/target,target=/app2,readonly,bind-propagation=rslave \
nginx:latest</code>Creating
/app/foo/also creates
/app2/foo/under the propagation setting.
SELinux label
Use the
zoption to share a bind mount among multiple containers, or
Zfor a private bind mount. Misusing
Zon system directories can render the host inoperable.
tmpfs mount
Supported only on Linux.
Tmpfs mounts keep data in host memory and disappear when the container stops, making them ideal for temporary or sensitive data. Unlike volumes and bind mounts, tmpfs cannot be shared between containers.
Usage
Mount with
--tmpfs(directly specifies the container path) or, for Docker 17.06+, use
--mountwith
type=tmpfs.
Options include
tmpfs-sizeand
tmpfs-mode.
volume drivers
Enable sharing data across machines.
Volume drivers abstract the underlying storage system, allowing you to switch between drivers (e.g., NFS, Amazon S3) without changing application code.
Usage
Create a volume with a driver:
<code>docker plugin install --grant-all-permissions vieux/sshfs</code> <code>docker volume create --driver vieux/sshfs \
-o sshcmd=test@node2:/home/test \
-o password=testpassword \
sshvolume</code>Run a container using the driver:
<code>docker run -d \
--name sshfs-container \
--volume-driver vieux/sshfs \
--mount src=sshvolume,target=/app,volume-opt=sshcmd=test@node2:/home/test,volume-opt=password=testpassword \
nginx:latest</code>Backup a container’s volume:
<code>docker run --rm --volumes-from dbstore -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata</code>Restore from backup:
<code>docker run -v /dbdata --name dbstore2 ubuntu /bin/bash</code> <code>docker run --rm --volumes-from dbstore2 -v $(pwd):/backup ubuntu bash -c "cd /dbdata && tar xvf /backup/backup.tar --strip 1"</code>Efficient Ops
This public account is maintained by Xiaotianguo and friends, regularly publishing widely-read original technical articles. We focus on operations transformation and accompany you throughout your operations career, growing together happily.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.