Skip to content

Docker Volume

Intro

In Docker, a volume is a mechanism for persistently storing and managing data generated by and used by Docker containers. It provides a way to share data between containers, as well as between the host machine and containers.

A Docker volume is a directory that is managed by Docker and is isolated from the container's file system. Volumes are typically created and managed using Docker commands or through Docker Compose files.

When a volume is created, it is associated with a specific container or multiple containers. The data stored in a volume persists even if the associated container is stopped or deleted. This allows for data to be shared and reused across different container instances.

Volumes have several advantages over other mechanisms, such as bind mounts. They are not dependent on the directory structure or operating system of the host machine, making them more portable. Volumes also support features like volume drivers, which enable integration with external storage systems, and can be easily managed and backed up by Docker.

Overall, volumes provide a flexible and efficient way to manage data in Docker containers, allowing for data persistence and sharing across containers and deployments.

UnionFS

Docker volumes are created and managed using a Linux kernel technology called Union File System or UnionFS. More specifically, Docker uses a copy-on-write (CoW) implementation of UnionFS, typically leveraging one of the following file system drivers:

  • aufs (Advanced Multi-Layered Unification File System): It was the original UnionFS implementation used by Docker. However, its support has been deprecated in recent versions of Docker.

  • overlay and overlay2 : These are the current default UnionFS drivers used by Docker. They provide better performance and stability compared to aufs.

  • btrfs (B-Tree File System): Docker can also use btrfs as a file system driver for volumes, but it requires specific configuration and may not be as widely used as overlay or overlay2.

These UnionFS file system drivers allow Docker to create lightweight, isolated, and efficient file system layers for containers. Docker volumes are essentially directories created within the UnionFS that are managed by Docker, providing a separate space for persistent data storage and sharing between containers.

We will learn more about UnionFS and container volumes in Docker images section.

Managing volume

This section includes some essential commands to provide a better understanding of Docker volumes. You may use the official Docker documentation as a reference.

  • Run a Nginx container using the below command:
docker run -it -d -p 8080:80 --name web nginx

Open a browser and navigate to http://localhost:8080. You should see the following NGINX welcome page.

Nginx Default

If you want to modify the HTML file, what is the solution?

  • Adding custom HTML using bind mounting volume:

Nginx, by default, searches for files to serve in the /usr/share/nginx/html directory within the container. To place our HTML files in this directory, we can utilize a mounted volume. This method allows us to connect a directory on our local machine and map it to the running container.

To serve a custom HTML page using the Nginx image, follow these steps:

  • Create a directory called html.
  • Within this directory, add an index.html file.
  • Paste the following HTML content into the index.html file:

<!DOCTYPE html>
<html>
<head>
    <title>CloudyNotes</title>
</head>
<body>
    <h1>Welcome to CloudyNotes.io</h1>
    <p>This is a Nginx container with a bind volume.</p>
</body>
</html>
- Run a new Nginx container with a bind volume:

docker run -it -d -p 8080:80 --name web -v <path_to_html>:/usr/share/nginx/html nginx

You should remove the other Nginx first.

Replace to the path of the html directory.

Now open the browser and navigate to http://localhost:8080 and you should see the above html rendered in your browser window:

Nginx bind volume

Try to modify the index.html and refresh the browser again. Are your changes applying on the ouput?

  • Inspect the container and find the binding details:
docker inspect web | grep Binds -A 5 -B 5
  • Now let's try to create a Docker volume:
docker volume create my_volume
  • Test the volume by adding a file to it:
echo "Hello, Docker volume!" | docker run -i --rm -v my_volume:/app busybox sh -c 'cat > /app/test.txt'

This command creates a file named "test.txt" inside the volume using a Busybox container.

  • Inspect the Docker volume:

docker inspect my_volume
- Navigate to the Mountpoint and check the content of the volume:

sudo su
cd /var/lib/docker/volumes/my_volume/_data
ls

Practice your knowledge

You can practice these tasks in a terminal or command prompt with Docker installed on your machine. Make sure you have Docker properly installed and configured before starting the practice scenario.

Remember to refer to Docker's official documentation for detailed information on each command and its usage. Happy learning!

Scenario1

Sharing Docker Volume Between Containers

In this scenario, you will practice creating a Docker volume, attaching it to two containers, and testing the sharing of the volume between the containers.

Task 1: Create Docker volume

Create a new Docker volume named my_volume.

Task 2: Run containers with same volume

Run the first container named container1 using the Nginx image. Attach the my_volume volume to the /app directory inside the container.

Run the second container named container2 using the Ubuntu image. Attach the same my_volume volume to the /app directory inside the container.

Task 3: Verify volume sharing

From container1, create a file named test.txt inside the volume with the content Hello from container1.

Hint: docker exec container1 sh -c 'echo "Hello from container1" > /app/test.txt'

Verify that the file is accessible from container2 and display its content.

Update the file from container2 with the content Hello from container2.

Verify that the changes are reflected when accessing the file from container1.

There are several ways to share data between containers. The above scenario was an example of file sharing using a bind volume. You can find more information here.

Comments