Persistent Data Storage in Docker: Docker Volumes and Bind Mounts
Accidently you executed docker rm -f mysql and that broke your entire application, but you are smart, you created the container again, but still the application is not able to bring old data.
You have seen some weird words in internet like –mount and then mydata:/some/path and you dont know what these means and how thats even related. Worry not, lets understand that and learn how to solve the problem of data lost and about the syntaxes that we see often on google or some document.
Lets see that together –
Docker containers are often ephemeral, meaning they’re designed to run processes and discard data upon exit(same as the first problem that we discussed above).
But what if you need certain data to persist beyond the lifecycle of a container? This is where persistent storage comes into play, allowing data to live on your host system(ex : laptop), even if containers are stopped, restarted, or deleted.
In this blog, we’ll cover three main aspects:
- What are Docker Volumes and Bind Mounts?
- How to Set Up Persistent Storage in Docker
- Benefits and Limitations of Different Docker Storage Options
Let’s dive into each phase to get a solid grasp on making data in Docker containers persist!
1. What Are Docker Volumes and Bind Mounts?
Docker offers two primary ways to manage persistent data:
- Volumes: Managed by Docker, volumes are stored in a specific Docker directory on the host, but Docker manages their lifecycle and storage location.
- Remember, if we dont give that volume a name, docker creates a random number and that becomes difficult to manage or attach with other containers.
- We human does not have any control, only docker can manage its lifecycle
- To know its location, we can do inspect of the container and look for mounts block (docker inspect mysql-container)
- Bind Mounts: Allows you to specify an exact path on your host machine to bind to a path within the container. With bind mounts, you control where the data lives.
- Generally developers uses this and map their development workspace with some directory inside the container
- The classic example is mapping the working space with nginx root path (source=$(pwd),target=/usr/share/nginx/)
- Or, mapping the log directory of container
Why Use Persistent Storage?
Persistent storage is crucial when dealing with databases, configuration files, application logs, or any data you want to access or maintain across container restarts.
For instance, without persistent storage, all the database data would disappear when a container is removed, making data recovery a challenge.
2. Setting Up Persistent Storage in Docker
Using Volumes in Docker
We can create volumes in Docker in three ways: inline while creating a container, with docker volume create
, or through docker-compose
.
Lets see all these 3 methods of creating volume in details below
Method 1: Creating a Named Volume Inline with --mount
To create a named volume directly when running a container, use the --mount
option:
docker run -d --name mysql-container --mount source=my_db_data,target=/var/lib/mysql mysql:latest
Here:
source=my_db_data
tells Docker to create a named volume calledmy_db_data
.target=/var/lib/mysql
this specifies the path inside the container where the volume will be mounted.
This approach is useful when you want Docker to manage the storage, ensuring data in /var/lib/mysql
persists even if the container is removed.
Method 2: Using docker volume create
To have more control over volume creation, you can create a volume first and then mount it to a container:
docker volume create my_app_data
docker run -d --name app-container --mount source=my_app_data,target=/app/data myapp:latest
Method 3: Using Docker Compose for Volumes
Docker Compose simplifies multi-container setups by defining configurations in a YAML file. Here’s how you can set up a volume in docker-compose.yml
:
version: '3.8'
services:
db:
image: mysql:latest
volumes:
- db_data:/var/lib/mysql
volumes:
db_data:
In this example, db_data
is a named volume that persists database files on the host.
Lets see, how many of you got this as a question or curiosity, as how to know which path inside the container needs to be mapped with some named volume in local laptop/host machine.
here, the colon (:) seperates the path between local & container and it can be read like this
local_laptop_path:inside_container_path
If you are curious, how to decide how to identify this path /var/lib/mysql inside the container db_data:/var/lib/mysql
Then to find the answer of this, we have to go to the public repo and see the image and the key informations are already present there.
Inspecting Docker Volumes
To verify the volume and its mount details, use:
docker inspect mysql-container
In the output, look for the Mounts
section to see details such as the Source
(host path) and Destination
(container path).
"Mounts": [
{
"Type": "volume",
"Name": "docker_dbdata",
"Source": "/var/lib/docker/volumes/docker_dbdata/_data",
"Destination": "/var/lib/mysql",
"Driver": "local",
"Mode": "z",
"RW": true,
"Propagation": ""
}
],
3. Using Bind Mounts for More Control
Bind mounts offer a different approach by giving you full control over where the data lives on the host. You specify the exact path on your host machine that should be accessible from within the container.
Creating a Container with a Bind Mount
docker run -d --name web-container --mount type=bind,source=$(pwd)/my-website,target=/usr/share/nginx/html -p 80:80 nginx
In this example:
type=bind
indicates that we’re using a bind mount.source=$(pwd)/my-website
points to themy-website
directory on the host machine.target=/usr/share/nginx/html
is the directory inside the container wheremy-website
will be accessible.
Just a side note:
We can pass more than two bind mounts through command, but, here we will see its difficult and it may produce errors, so the discovery of docker compose made it better.
docker run -d \
--name website \
-p 80:80 \
--mount type=bind,source=$(pwd)/website_files,target=/usr/share/nginx/html \
--mount type=bind,source=$(pwd)/nginx_logs/error.log,target=/var/log/nginx/error.log \
website
To know more about docker compose, please read it from here https://www.liainfraservices.com/blog/how-to-set-up-a-local-development-environment-using-docker-compose/
If you inspect this container with docker inspect web-container
, the Mounts
section will reveal the host directory bound to the container’s filesystem:
“Mounts”: [
{
“Type”: “bind”,
“Source”: “/Users/macbook/my-website”,
“Destination”: “/usr/share/nginx/html”,
“RW”: true
}
]
Advantages of Bind Mounts
- Full control: You decide exactly where on the host the data lives.
- Real-time updates: Any changes made on the host directory are immediately reflected in the container, and vice versa.
4. Benefits and Limitations of Docker Volumes vs. Bind Mounts
Both storage methods have their own pros and cons:
Feature | Volumes | Bind Mounts |
---|---|---|
Managed by | Docker | Host (defined path) |
Flexibility | Docker decides storage location | User specifies exact path |
Security | More secure, Docker manages permissions | Less secure, full access to host path |
Sharing Data | Easily shared among containers | Possible but with extra caution |
Suitability | Suitable for app data, databases, logs | Great for development, real-time updates |
Example Scenarios:
- Use named volumes for production databases, app data, or logs that need persistence but minimal intervention.
- Use bind mounts in development to reflect host changes in real-time within containers, which is ideal for working with code or config files.
Persistent data is a core aspect of any application relying on Docker containers, whether in development or production. Understanding when to use volumes versus bind mounts helps you make smart storage decisions that suit your application’s needs.
By following this guide, you now know:
- How to create volumes and bind mounts in Docker.
- How to configure persistent data with Docker Compose.
- The benefits and limitations of each storage type.
If you enjoyed so far, then I am sure you will enjoy this also where I dived deep into docker compose: https://www.liainfraservices.com/blog/how-to-set-up-a-local-development-environment-using-docker-compose/

Partho Das, founder of Lia Infraservices, has 15+ years of expertise in cloud solutions, DevOps, and infrastructure security. He provides consultation on architecture planning, DevOps setup, Kubernetes, and cloud migrations. Partho holds multiple AWS and Azure certifications, along with CISCO CCNA & CCNP.
Connect on LinkedIn