Volumes are files or directories mounted from the host. They are not part of the union filesystem, so other containers can share them and changes land directly on the host filesystem.
Declare a volume in a Dockerfile with VOLUME or at runtime with -v on docker run.
Declaring a volume
Mark /data as a volume inside the container:
# Dockerfile
VOLUME /data
docker run -v /data test/webserver
By default the path is mounted under Docker’s data directory on the host (usually
/var/lib/docker/).
Find the host path:
docker inspect -f {{.Mounts}} <container-name>
Example output:
[{5cad... /mnt/sda1/var/lib/docker/volumes/5cad.../_data /data local true}]
Custom mount point
Point a host directory at a container path:
docker run -d -v /host/dir:/container/dir test/web-server
You cannot set a host path in a Dockerfile — portability and security (containers must not mount sensitive paths like /etc/passwd without explicit permission).
Volume permissions and Dockerfile order
Any instruction after VOLUME in a Dockerfile does not change that volume. This Dockerfile will not work as expected:
FROM debian:wheezy
RUN useradd foo
VOLUME /data
RUN touch /data/x
RUN chown -R foo:foo /data
The touch and chown run in a temporary build container layer volume that is discarded, so the last two instructions have no lasting effect.
Correct order:
FROM debian:wheezy
RUN useradd foo
RUN mkdir /data && touch /data/x
RUN chown -R foo:foo /data
VOLUME /data
When you start a container from this image, Docker copies files from the image’s volume directory into the container volume — unless you bind-mount an existing host directory (to avoid overwriting host data).
Sharing data between containers
Mount the same host files into multiple containers built from the same image — useful for config files.
Share another container’s volumes with --volumes-from:
docker run -it -h NEWCONTAINER --volumes-from container-test debian /bin/bash
This works whether the source container is running or stopped. A volume cannot be removed while any container still references it.
Data containers
A data container exists only to hold volumes for other containers. It gives volumes a stable name you can attach with --volumes-from.
Create a PostgreSQL data container:
docker run --name dbdata postgres echo "Data-only container for postgres"
Volumes from the postgres image are initialized before echo runs and the container exits. Data containers do not need to stay running.
Use its volumes from another container:
docker run -d --volumes-from dbdata --name db1 postgres
DigitalOcean block storage plugin
Install the Rex-Ray DigitalOcean block storage plugin:
docker plugin install rexray/dobs \
DOBS_REGION=<DO_REGION> \
DOBS_TOKEN=<DIGITAL_OCEAN_TOKEN> \
DOBS_CONVERTUNDERSCORES=true
Create a volume with a driver:
docker volume create -d [DRIVER] [NAME]
Use it in a service:
docker service create -d --name [NAME] \
--mount type=[TYPE],src=[SOURCE],dst=[DESTINATION] \
-p [HOST_PORT]:[CONTAINER_PORT] \
--replicas [REPLICAS] \
[IMAGE] [CMD]
Related topics
- Storage — volumes vs bind mounts vs ephemeral layers
- Connecting containers — network links between containers
Andrew Dorokhov