Docker Volumes: Simple Explanation with Hands-On Examples

Anusha KothaAnusha Kotha
7 min read

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. ❤️

0
Subscribe to my newsletter

Read articles from Anusha Kotha directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Anusha Kotha
Anusha Kotha