Cloud Native 27 min read

Docker Data Management: Volumes and Bind Mounts – Theory and Practice

This tutorial explains Docker's data management techniques, covering the concepts and hands‑on steps for using volumes and bind mounts, how to back up logs and MongoDB data, and how to restore them, providing a complete guide for reliable container data handling.

Sohu Tech Products
Sohu Tech Products
Sohu Tech Products
Docker Data Management: Volumes and Bind Mounts – Theory and Practice

Docker Data Management Overview

Data is the core of all applications and services, and after witnessing repeated "delete‑database‑run‑away" incidents, the importance of data storage and backup becomes crystal clear. Docker offers a convenient and powerful way to handle container data. This article guides you through both theory and practical steps to master Docker's two common data management methods—Volumes and Bind Mounts—so you can manage data confidently and keep your applications well‑supported.

Docker Data Management Overview

Welcome back to the "Dream Builder" Docker tutorial series. Previously we introduced Docker images and containers by comparing "work" and "dreaming" and performed small experiments to understand how Docker turns a dream into reality, covering the key concepts of images and containers.

In the earlier article "Networking to Connect Containers," we learned that different containers can communicate via Docker networks.

In this tutorial we will bridge the "dream" (container environment) and the "reality" (host environment). Docker data management mainly consists of three methods:

Volume (the most recommended method)

Bind Mount (an early Docker data management method)

tmpfs Mount (memory‑based data management, not covered in this tutorial)

Note tmpfs mounts are only applicable on Linux operating systems.

We will now walk through a few small experiments; readers already familiar with the concepts can skip directly to the "Hands‑On Practice" section.

Volumes

Basic Commands

As mentioned in the previous article, a volume is a common Docker object type, supporting commands such as create , inspect , ls , prune , and rm .

Let's go through a workflow:

docker volume create my-volume

List all volumes:

docker volume ls

The output shows the newly created my-volume :

local               my-volume

Inspect the volume details:

docker volume inspect my-volume

The command returns JSON information about my-volume :

[
    {
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/my-vol/_data",
        "Name": "my-volume",
        "Options": {},
        "Scope": "local"
    }
]
Tip On non‑Linux systems (Windows and macOS) the directory /var/lib/docker/volumes does not exist on the host file system; it resides inside Docker's virtual machine.

Finally, delete the volume:

docker volume rm my-volume

A single volume alone is not very useful; its purpose is to serve container data. The diagram below (source: Safari Books Online) shows how a volume bridges the host and container environments.

The volume creates a bridge between the host and container, allowing data written inside the container to be automatically stored on the host.

When creating a container with a volume, you have two options: (1) Named Volume and (2) Anonymous Volume . The following sections explain each in detail.

Creating a Named Volume

Run a container with a named volume:

docker run -it -v my-vol:/data --name container1 alpine

The -v (or --volume ) flag maps my-vol:/data , where my-vol is the volume name and /data is the mount point inside the container.

Inside the container, create a file in /data and exit:

# touch /data/file.txt
# exit
Note The prompt / # is the default Alpine shell prompt; the actual command to run is touch /data/file.txt .

To verify that the file persisted, remove container1 and start a new container container2 with the same volume:

docker rm container1
docker run -it -v my-vol:/data --name container2 alpine
# ls /data
file.txt
# exit

The file is still present, demonstrating that volumes enable data sharing between containers. Docker also provides the --volumes-from flag to share volumes easily:

docker run -it --volumes-from container2 --name container3 alpine
# ls /data
file.txt

Container container3 can also access the same data.

Creating an Anonymous Volume

Creating an anonymous volume is simpler; omit the volume name:

docker run -v /data --name container4 alpine

Inspect the container to see the generated random volume name:

docker inspect container4

The Mounts field shows details such as Name (a long random string), Source (host path), Destination ( /data ), and RW (read‑write flag).

Using Volumes in a Dockerfile

Declare a volume in a Dockerfile with the VOLUME instruction:

VOLUME /data
# or using a JSON array for multiple volumes
VOLUME ["/data1", "/data2", "/data3"]

Two important notes:

Only anonymous volumes can be created this way.

If you later run docker run -v , the Dockerfile's volume configuration will be overridden.

Bind Mounts

Bind mounts were the earliest Docker data management solution. They map a host file system path directly to a container path, making them simple and flexible for data exchange.

Example: mount your desktop into a container:

docker run -it --rm -v ~/Desktop:/desktop alpine

The -v flag maps ~/Desktop (host) to /desktop (container). The --rm flag removes the container after it stops.

Inside the container, list /desktop and create a file to see it appear on the host:

# ls /desktop
# touch /desktop/from-container.txt

The file from-container.txt now exists on your desktop.

Summary

Official documentation diagram:

Volumes store container data in a dedicated area on the host file system.

Bind mounts create a direct mapping between host and container file systems.

tmpfs mounts keep data in memory (not covered here).

When specifying a volume or bind mount, the -v syntax is <source>:<target>:<options> , where the third field (e.g., ro ) makes the mount read‑only.

Tip Since Docker 17.06, the --mount flag provides a more explicit key‑value syntax that mirrors -v functionality.

Hands‑On Practice

Preparation and Goal

We will now deploy a full‑stack todo application (React front‑end, Express back‑end, MongoDB). The goals are to store and back up Express server logs outside the transient container and to back up and restore MongoDB data.

Mount a Volume for the Express Server

Add a VOLUME line to server/Dockerfile and set the LOG_PATH environment variable to /var/log/server/access.log :

# ...
# Set working directory
WORKDIR /usr/src/app

VOLUME /var/log/server

# ...
ENV MONGO_URI=mongodb://dream-db:27017/todos
ENV HOST=0.0.0.0
ENV PORT=4000
ENV LOG_PATH=/var/log/server/access.log
# ...

Build the server image:

docker build -t dream-server server/

Start the whole stack:

# Create a network for container communication
docker network create dream-net

# Start MongoDB container
docker run --name dream-db --network dream-net -d mongo

# Start Express API container
docker run -p 4000:4000 --name dream-api --network dream-net -d dream-server

# Build and run the React front‑end (Nginx) container
docker build -t dream-client client
docker run -p 8080:80 --name client -d dream-client

Verify all three containers are running with docker ps (screenshot omitted).

Open http://localhost:8080 , create a few todo items (screenshot omitted).

Backing Up Log Data

Because logs are stored in an anonymous volume, we back them up by creating a temporary container that shares the volume and binds a host directory:

docker run -it --rm --volumes-from dream-api -v $(pwd):/backup alpine

Inside the temporary container, compress the log directory:

# tar cvf /backup/backup.tar /var/log/server/

Alternatively, perform the whole operation in one command:

docker run -it --rm --volumes-from dream-api -v $(pwd):/backup alpine tar cvf /backup/backup.tar /var/log/server

Database Backup and Restore

We will use MongoDB's mongodump and mongorestore utilities. First backup using a temporary container that shares the dream-db network and binds a host directory:

docker run -it --rm -v $(pwd):/backup --network dream-net mongo sh

Inside the container, run:

# mongodump -v --host dream-db:27017 --archive --gzip > /backup/mongo-backup.gz

The backup file appears in the current host directory.

Alternatively, if the database container was started with a bind mount, you can back up directly with:

docker exec dream-db sh -c 'mongodump -v --archive --gzip > /backup/mongo-backup.gz'

If the container was not originally started with a bind mount, this method will not work.

Disaster Recovery Exercise

Delete the database and API containers (including their volumes):

docker rm -f --volumes dream-db
docker rm -f dream-api

Re‑create the database container with a bind mount to the host backup directory:

docker run --name dream-db --network dream-net -v $(pwd):/backup -d mongo

Restore the data:

docker exec dream-db sh -c 'mongorestore --archive --gzip < /backup/mongo-backup.gz'

Finally, restart the API container:

docker run -p 4000:4000 --name dream-api --network dream-net -d dream-server

Visiting the todo app again should show the restored data.

Recall and Elevation

Another Way to Share Data: docker cp

You can copy files between a container and the host with docker cp :

docker cp dream-api:/var/log/server/access.log .

And copy from host to container:

docker cp /path/to/some/file dream-api:/dest/path

While convenient for one‑off operations, docker cp requires manual path knowledge and does not scale well for repeated workflows.

Another Backup/Restore Method: docker export/import

Export an entire container's filesystem to a tar archive:

docker export my-container > my-container.tar
Note export does not include the contents of data volumes.

Import the tar archive as a new image:

docker import my-container.tar

The command outputs a SHA256 image ID, which can be run or tagged as needed.

Exported tar files can be hundreds of megabytes because they contain the entire container filesystem, not just the application data.

Root Cause: Union File System (UFS)

Docker uses a Union File System to layer read‑only image layers with a writable layer for each container. Data written to the writable layer disappears when the container is removed, which is why volumes and bind mounts are essential for persisting important data.

This article demonstrates how to bypass UFS for reliable data storage, backup, and recovery.

All source code referenced in this article is available on GitHub . If you found this article helpful, please give it a like.

References

[1] "A Cup of Tea to Get Started with Docker": https://juejin.im/post/5e0f43bd5188253aa83e29d2

[2] "Dreams Interconnected: Using Network to Connect Containers": https://juejin.im/post/5e1b1072e51d453c9e1550ff

[3] tmpfs mounts: https://docs.docker.com/storage/tmpfs/

[4] Previous article: https://juejin.im/post/5e1b1072e51d453c9e1550ff

[5] Safari Books Online: https://www.oreilly.com/library/view/continuous-delivery-with/9781787125230/8af8e5f4-66d5-4fe7-8709-2b5e1ae4acdf.xhtml

[6] First article: https://juejin.im/post/5e0f43bd5188253aa83e29d2

[7] Docker documentation on volumes: https://docs.docker.com/storage/volumes

[8] Previous article: https://juejin.im/post/5e1b1072e51d453c9e1550ff

[9] Earlier tutorial: https://juejin.im/post/5e1b1072e51d453c9e1550ff

[10] The Docker Ecosystem: https://legacy.gitbook.com/book/washraf/the-docker-ecosystem/details

[11] GitHub repository: https://github.com/tuture-dev/docker-dream

DockerDevOpsdata backupContainersBind MountsVolumes
Sohu Tech Products
Written by

Sohu Tech Products

A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.