Docker Day 5: Everything you need to know about Docker Volumes and Bind Mounts
Introduction
As we have seen so far, we know that Docker is a platform which implements the concept of Containerization. One of the features of Containers is that they are Ephemeral in nature by default. It means that any data stored within the container is lost when the container goes down. And a container can go down for many reasons.
This Ephemeral nature is not ideal as persistent storage of the data within the container is very important for high availability of the application. Lets understand this problem with a few scenarios.
Imagine all the log data of your application is stored in the container. And the container went down for some reasons. Now, you lose all the crucial log data.
Imagine, Hashnode hosted its front-end on one container and the back-end(DB) on another container. The data in the back-end(blogs) is served to the front-end for the user to access and read it. Now, if the back-end container goes down, viewers on Hashnode will not be able to read the blogs.
No company would afford to lose such data, so it is important to store the data irrespective to the container's lifecycle i.e., whether the container goes down or is up and running.
Docker volumes and bind mounts are both mechanisms for persisting data between the Docker host and containers, but they work in slightly different ways and are suited for different use cases, which we will be discussing in this blog.
Docker Volumes
Docker volumes are managed by Docker and are stored within the Docker data directory.
Managed by Docker: Docker volumes are managed by Docker itself, making them easy to create, manage, and back up.
Persistent Storage: Volumes persist even after the container using them is stopped or deleted, allowing data to be retained across container restarts.
Efficient and Fast: Volumes are more efficient and faster compared to bind mounts because they do not involve the overhead of host file system operations.
Recommended for Production: Docker volumes are recommended for production use cases where data persistence, management, and scalability are important.
The seconds scenario is solved here. Now, Hashnode can store all the blogs on a DB container with docker volumes attached and the blogs will persist even if the container stops or shuts down.
Creating Docker Volumes
Create the Docker Volume using -
docker volume create db_data
Now, mount the Volume to any desired container
docker run -d --name db_container -v db_data:/var/lib/mysql mysql:latest
The
-v
flag mounts thedb_data
volume to the/var/lib/mysql
directory inside the container. This ensures that the database data is stored in the Docker volume.Can also mount the volume using the
--mount
flag.docker run -d --mount source=db_data,target=/var/lib/mysql mysql:latest
You can get a list of all created volumes using -
docker volume ls
Inspect a volume to get additional data -
docker volume inspect <name-of-volume>
Bind Mounts
Bind mounts are specific paths on the host file system that are mounted into a container. Unlike volumes, bind mounts are managed by the host system and can be any directory or file on the host.
Managed by Host: Bind mounts are managed by the host file system, allowing you to access host files and directories from within the container.
No Data Duplication: Changes made to files or directories in a bind mount are immediately visible on both the host and the container, as they share the same underlying data.
Flexible: Bind mounts provide more flexibility and control over where data is stored, making them suitable for development and local testing environments.
Performance Impact: Bind mounts can have a performance impact, especially on macOS and Windows hosts, due to the overhead of file system translation.
Consider a scenario where you are developing a Node.js application locally using Docker containers. You want to make changes to the application code on your host machine and immediately see the changes reflected in the Docker container without rebuilding the image. Bind Mounts are useful in such scenarios.
Creating Bind Mounts
You directly create a bind mount by specifying the host path and container path when running the container:
`docker run -d --name mycontainer -v /host/path:/container/path myimage
To create a bind mount for the node.js scenario
docker run -d --run myapp -v "$(pwd)":/app my-nodejs-image:latest
The
-v
flag mounts the current working directory ($(pwd)
) on the host machine to the/app
directory inside the container. This allows you to access and modify the application code from both the host and the container.
Conclusion
In summary, Docker volumes are recommended for production use cases where data persistence and management are critical, while bind mounts provide flexibility and control over data storage, making them suitable for development and local testing environments. Choose the appropriate mechanism based on your specific use case and requirements.
Happy Containerization!
Subscribe to my newsletter
Read articles from Rachana directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Rachana
Rachana
Hi to the fellow tech enthusiasts out there! π I am an aspiring Cloud and DevOps Engineer βοΈ With strong foundation in containerization technologies like Docker and Kubernetesπ³ Capable of building resilient, secure and cost optimized infrastructure on AWS cloud - AWS SAA certified.βοΈπ Currently learning to build CI/CD pipelines using Jenkins, github-actions, AWS CodePipeline, and many more.π οΈπ Exploring other tools like Ansible for configuration management and Terraform for Infrastructure as Code(IaC).π§©π Let's connect, learn and grow together! ππ€