Mastering Docker Persistent Storage: Volumes, Bind Mounts, and Tmpfs Explained
This article explains why storing data in a container’s layer is problematic and details Docker’s three persistent storage options—volumes, bind mounts, and tmpfs—along with their commands, configurations, use‑cases, and advanced features such as volume drivers and bind propagation.
Data stored in a container’s layer is not persistent: it disappears when the container is removed, is hard for host processes to access, and incurs performance overhead due to the storage driver.
Docker offers three ways to achieve persistent data storage:
volumes : Managed by Docker in a directory on the host filesystem (e.g.,
docker volume create). Volumes survive container removal, can be shared read‑write or read‑only among multiple containers, and are the recommended method for persistent data.
bind mount : Maps any host directory or file into a container. Non‑Docker processes can modify the data, and Docker will create the host directory if it does not exist when using
-vor
--volume.
tmpfs mount (Linux only): Stores data in host memory; it is not written to disk and disappears when the container stops, making it suitable for temporary or sensitive data.
volumes
If a volume is not explicitly created, Docker creates it on first mount and keeps it after the container stops. Deleting a volume requires an explicit command.
When mounting an empty volume onto a directory that already contains files, Docker copies those files into the volume; mounting a non‑empty volume hides the existing files.
Usage
Create a volume:
docker volume createRemove a specific volume:
docker volume rm <volume_name>Remove all unused volumes:
docker volume pruneList volumes:
docker volume lsInspect a volume:
docker volume inspect <volume_name>Mount to a container:
-vor
--volume(Docker 17.06+ prefers
--mount)
Mount options include type (bind, volume, tmpfs), source, destination, read‑only flag, and driver‑specific options such as
volume-opt.
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’s directory layout.
Backup, restore, or migration of data between Docker hosts.
bind mount
A bind mount references a host file or directory by its absolute path. The host path does not need to exist beforehand; Docker will create it when using
-vor
--volume.
If a bind mount hides existing files in the container’s target directory, they become invisible; if the host path is missing, Docker reports an error with
--mountbut creates the directory with
-v/
--volume.
Usage
Mount to a container with
-vor
--volume; Docker 17.06+ recommends
--mount.
Mount syntax for
-v/
--volume:
source:target[:options]Mount syntax for
--mount:
type=bind,source=<path>,target=<path>[,options]Scenarios
In general, prefer volumes when possible.
Sharing configuration files (e.g.,
/etc/resolv.conf) between host and container.
Sharing source code or build artifacts.
Ensuring host directory structure matches container expectations.
bind propagation
By default bind mounts are rprivate ; propagation can be changed on Linux, but most users do not need to configure it.
Propagation determines whether a mount created inside one mount point is visible at another mount point.
Example:
<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/due to
rslavepropagation.
SELinux label
Use the
z(shared) or
Z(private) options to modify the SELinux label of the host path in the container. Misusing
Zon system directories can render the host inoperable.
tmpfs mount
Supported only on Linux.
Tmpfs mounts keep data in host memory, are removed when the container stops, and cannot be shared between containers, making them ideal for temporary or sensitive data.
Usage
Mount with
--tmpfs(or
--mounton Docker 17.06+).
Options include
type=tmpfs,
destination,
tmpfs-size, and
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 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.