Docker Volumes: Simple Explanation with Hands-On Examples

When working with Docker, I noticed that there are four main building blocks: Images, Containers, Volumes, and Networks. In this blog, we’ll focus on Docker Volumes. Volumes are the best way to save data created or used by containers, so it doesn’t get lost when the container stops or is removed. In this post, we’ll explain what Docker volumes are and show real-life examples of how to use them.
What Are Docker Volumes?
A Docker Volume is a way to save data outside the container, so it doesn't get lost when the container stops or gets deleted. It's like giving your container a safe place to store files that will stay even if the container is removed.
Normally, when a container saves data, it stores it inside itself. But this data is temporary. If you stop or delete the container, the data disappears too. To fix this, Docker lets you attach a volume to the container. This volume stores data permanently, outside the container.
So, even if you delete the old container and create a new one, you can reuse the same volume and get your data back.
Think of a Docker container as a whiteboard that you use during a meeting.
When the meeting ends, the whiteboard is wiped clean and all the notes are lost.
A Docker Volume is like a notebook where you write down important notes during the meeting.
Even after the meeting is over, the notes stay safe in the notebook and you can look at them anytime.
So, with Docker volumes, the data inside your container stays safe and can be reused, even if the container itself is deleted.
Why use Docker Volumes in Production?
In production, we often run multiple containers for the same service to handle more users or workload.
It can be hard to keep the data and configuration updated and consistent across all containers.
Docker Volumes help by sharing data between containers.
If you update data in one container, the changes are available in all containers using the same volume.
Common Docker Volume Commands
- Create a volume:
docker volume create volume-name
List all volumes:
docker volume ls
See detailed info about a volume:
docker volume inspect volume-name
Delete a volume:
docker volume rm volume-name
Note: You cannot delete a volume if it is still attached to any container. Detach it first.
Delete multiple volumes at once:
docker volume rm volume1 volume2 volume3
Remove all unused volumes:
docker volume prune
Practical Example: Create and Use a Volume
1. Create a volume called zepto:
docker volume create zepto
2. Inspect the volume details:
docker volume inspect zepto
You will see something like this, showing where the volume data is stored on your host:/var/lib/docker/volumes/zepto/_data
3.Run a container and mount the volume inside it:
docker run -itd --name cont1 --mount src=zepto,destination=/myapp ubuntu
Inside the container, the folder /myapp
is linked to the zepto
volume.
4.Check the folder inside the container:
docker exec -it cont1 bash
cd /myapp
Create some files and folders here:
touch file{1..4}
mkdir devops{1..3}
ls
5.Exit the container and check the volume data on the host:
cd /var/lib/docker/volumes/zepto/_data/
ls
You will see the same files and folders you created inside the container.
6.If you add files here on the host, they will also appear inside the container.
Adding files on host
touch anu{1..4}
mkdir anusha{1..3}
ls
Now lets go to cont1 and check the files present in myapp folder.
docker exec -it cont1 bash
cd /myapp
👉 Note: We can clearly see that data syncs between the container and the host. By mounting the same volume to multiple containers, we can easily share and replicate the data across them.
Host to Container (Bind Mounts):
Bind mounts have been used in Docker since its early days. They allow you to connect a file or directory from your Docker host directly to the container’s file system. If the specified file or folder isn’t present inside the container, Docker will automatically create it when the container starts. Any updates made on the host will instantly reflect inside the container, and vice versa—changes inside the container will also appear on the host.
While this is convenient, it does come with security concerns. For instance, if a process inside the container modifies a file, that change will also affect the original file on the host. Therefore, bind mounts should be used with caution.
Bind mounts are particularly handy during development. By linking your project folder to the container, you can see code changes reflected immediately inside the container without rebuilding the image each time. This speeds up the development process significantly.
Practical use case of bind mounts:
lets create a folder in Dockerhost
mkdir swiggy && cd swiggy
now create some files
touch index.html app.py style.css requirements.txt
Now lets create the container inside the same directory:
docker run -itd --name cont5 -v "$(pwd)":/appcode ubuntu
Now lets get into the container and check the same files
docker exec -it cont5 bash
cd appcode
Now lets create some files inside the container, that will replicate in Dockerhost on the same swiggy folder
touch anusha blinkit zepto dunzo
Now lets exit from container and check in docker host
Similarly, the data is shared between the host and the container. By using the same path, we can create multiple containers that all have access to the same replicated data.
In the above two methods, we saw that data is shared in both directions — from host to container and from container to host. This can be risky because if something inside the container changes a file, it will also change the file on the host. To avoid this, we should use read-only volumes so that containers can only read the data but cannot change it.
Read-Only Volumes
We can make a volume read-only, so the container can only read data from it but cannot write or make changes. This is useful when there are security concerns, based on the application's needs. Read-only volumes are set at the time of creating the container.
command to create a container with read only volume:
docker run -itd --name kotha -v uber:/app:ro ubuntu
In the above command, uber is the volume that will created on host, and /app is the path where we mounted inside the container. ro represents the readonly volume.
Now lets enter into the container and add some data on /app folder, we will get permission denied error.
docker exec -it kotha bash
cd app
See, we can’t write the data from container, but if we write the data on uber volume in docker host, it will replicate here.
Sharing the volumes from container-container
we can share the volume from one container to another container while creating.
docker run -itd --name aws --privileged=true --volumes-from=kotha ubuntu
In the above command, we can see the volumes from kotha container is going to share with aws container.
Creating a volume using Dockerfile
Not only with the commands, we can also create the docker volumes with Dockerfile
FROM ubuntu
VOLUME [/mycode]
If we build the above Dockerfile and run the image, automatically a container and a random volume will be created. Now the volume will present inside the volume, when ever we run the image, automatically this volume will creates.
Conclusion
I hope this blog was helpful for you. I’ve tried to explain all the basic concepts of Docker volumes and mounts that beginners should know. There’s still a lot more to learn, which I’ll cover in future blogs.
If this blog helped you in your interviews or while learning Docker troubleshooting, show some love! 💖
Tap the heart button 10 times and leave a comment. Your support encourages me to create more content on DevOps and similar topics. ❤️
Subscribe to my newsletter
Read articles from Anusha Kotha directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
