avatarMahbub Zaman

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

5010

Abstract

volumes/4e679725b7179e63e8658bc157a1980f320948ab819f271fd5a44fe94c16bf23/_data"</span>, <span class="hljs-string">"Destination"</span>: <span class="hljs-string">"/var/lib/mysql"</span>, <span class="hljs-string">"Driver"</span>: <span class="hljs-string">"local"</span>, <span class="hljs-string">"Mode"</span>: <span class="hljs-string">""</span>, <span class="hljs-string">"RW"</span>: <span class="hljs-literal">true</span>, <span class="hljs-string">"Propagation"</span>: <span class="hljs-string">""</span> } ], . . .</pre></div><p id="1516">We can use the following <a href="https://docs.docker.com/engine/reference/commandline/rm/">command</a> to remove the container and its associated anonymous volume.</p><div id="45c5"><pre>docker <span class="hljs-built_in">rm</span> -v mysql_db_1</pre></div><p id="2786">If we don’t remove the anonymous volume and the container together, it becomes a dangling volume.</p><div id="40e6"><pre>docker <span class="hljs-built_in">rm</span> mysql_db_1</pre></div><p id="3749">We can list and remove all the dangling volumes using the following commands.</p><div id="6fb1"><pre>docker volume <span class="hljs-built_in">ls</span> -qf dangling=<span class="hljs-literal">true</span> docker volume <span class="hljs-built_in">rm</span> (docker volume <span class="hljs-built_in">ls</span> -qf dangling=<span class="hljs-literal">true</span>)</pre></div><h2 id="ccc9">2. Named volumes</h2><p id="80a7">Named volumes can persist data after we restart or remove a container. Also, it’s accessible by other containers. These volumes are created inside <code>/var/lib/docker/volume</code> local host directory.</p><div id="e313"><pre><span class="hljs-attr">version:</span> <span class="hljs-string">'3.8'</span> <span class="hljs-attr">services:</span> <span class="hljs-attr">db:</span> <span class="hljs-attr">image:</span> <span class="hljs-string">mysql</span> <span class="hljs-attr">restart:</span> <span class="hljs-string">always</span> <span class="hljs-attr">environment:</span> <span class="hljs-attr">MYSQL_ROOT_PASSWORD:</span> <span class="hljs-string">root</span> <span class="hljs-attr">MYSQL_DATABASE:</span> <span class="hljs-string">test_db</span> <span class="hljs-attr">ports:</span> <span class="hljs-bullet">-</span> <span class="hljs-string">"3306:3306"</span> <span class="hljs-attr">volumes:</span> <span class="hljs-bullet">-</span> <span class="hljs-string">db_data:/var/lib/mysql</span> <span class="hljs-attr">volumes:</span> <span class="hljs-attr">db_data:</span></pre></div><p id="d04d">Here, the first field is a unique name of the volume on a host machine. The second part is the path in the container.</p><p id="fb7d">Moreover, if we remove the container using the following command, we will still have the volume, unlike anonymous volumes.</p><div id="f292"><pre>docker <span class="hljs-built_in">rm</span> -v mysql_db_1</pre></div><h2 id="643d">3. Bind mounts</h2><p id="ca15">Bind mounts can persist data after we restart or remove a container. As we can see, named volumes and bind mounts are the same, except the named volumes can be found under a specific host directory, and bind mounts can be in any host directory.</p><div id="8a29"><pre><span class="hljs-attr">version:</span> <span class="hljs-string">'3.8'</span> <span class="hljs-attr">services:</span> <span class="hljs-attr">db:</span> <span class="hljs-attr">image:</span> <span class="hljs-string">mysql</span> <span class="hljs-attr">restart:</span> <span class="hljs-string">always</span> <span class="hljs-attr">environment:</span> <span class="hljs-attr">MYSQL_ROOT_PASSWORD:</span> <span class="hljs-string">root</span> <span class="hljs-attr">MYSQL_DATABASE:</span> <span class="hljs-string">test_db</span> <span class="hljs-attr">ports:</span> <span class="hljs-bullet">-</span> <span class="hljs-string">"3306:3306"</span> <span class="hljs-attr">volumes:</span> <span class="hljs-bullet">-</span> <span class="hljs-string">PWD/data:/var/lib/mysql</span></pre></div><p id="20c2">Here, we are mounting a host folder. The first part is the path in the host machine. The second part is the path in the container.</p><h1 id="ef92">Commands</h1><p id="82e8">Now, let’s list all the available commands for the volume instruction.</p><div id="565e"><pre>docker volume --<span class="hljs-built_in">help</span>

Commands: create Create a volume inspect Display detailed information on one or more volumes <span class="hljs-built_in">ls</span> List volumes prune Remove all unused <span class="hljs-built_in">local</span> volumes <span class="hljs-built_in">rm</span> Remove one or more volumes</pre></div><p id="2427">We can use these commands to manage anonymous volumes and named volumes.</p><div id="adc6"><pre><span class="hl

Options

js-meta prompt_"># </span><span class="language-bash">Creat a volume</span> docker volume create test-vol <span class="hljs-meta prompt_"># </span><span class="language-bash">test-vol</span> <span class="hljs-meta prompt_">

</span><span class="language-bash">Inspect a volume</span>

docker inspect test-vol <span class="hljs-meta prompt_"># </span><span class="language-bash">[</span> <span class="hljs-meta prompt_"># </span><span class="language-bash"> {</span> <span class="hljs-meta prompt_"># </span><span class="language-bash"> <span class="hljs-string">"CreatedAt"</span>: <span class="hljs-string">"2021-07-17T07:23:25Z"</span>,</span> <span class="hljs-meta prompt_"># </span><span class="language-bash"> <span class="hljs-string">"Driver"</span>: <span class="hljs-string">"local"</span>,</span> <span class="hljs-meta prompt_"># </span><span class="language-bash"> <span class="hljs-string">"Labels"</span>: {},</span> <span class="hljs-meta prompt_"># </span><span class="language-bash"> <span class="hljs-string">"Mountpoint"</span>: <span class="hljs-string">"/var/lib/docker/volumes/test-vol/_data"</span>,</span> <span class="hljs-meta prompt_"># </span><span class="language-bash"> <span class="hljs-string">"Name"</span>: <span class="hljs-string">"test-vol"</span>,</span> <span class="hljs-meta prompt_"># </span><span class="language-bash"> <span class="hljs-string">"Options"</span>: {},</span> <span class="hljs-meta prompt_"># </span><span class="language-bash"> <span class="hljs-string">"Scope"</span>: <span class="hljs-string">"local"</span></span> <span class="hljs-meta prompt_"># </span><span class="language-bash"> }</span> <span class="hljs-meta prompt_"># </span><span class="language-bash">]</span> <span class="hljs-meta prompt_">

</span><span class="language-bash">List all volumes</span>

docker volume create test-vol-2 docker volume ls <span class="hljs-meta prompt_"># </span><span class="language-bash">DRIVER VOLUME NAME</span> <span class="hljs-meta prompt_"># </span><span class="language-bash"><span class="hljs-built_in">local</span> test-vol</span> <span class="hljs-meta prompt_"># </span><span class="language-bash"><span class="hljs-built_in">local</span> test-vol-2</span> <span class="hljs-meta prompt_">

</span><span class="language-bash">Remove all volumes</span>

docker volume prune <span class="hljs-meta prompt_"># </span><span class="language-bash">WARNING! This will remove all <span class="hljs-built_in">local</span> volumes not used by at least one container.</span> <span class="hljs-meta prompt_"># </span><span class="language-bash">Are you sure you want to <span class="hljs-built_in">continue</span>? [y/N] y</span> <span class="hljs-meta prompt_"># </span><span class="language-bash">Deleted Volumes:</span> <span class="hljs-meta prompt_"># </span><span class="language-bash">test-vol</span> <span class="hljs-meta prompt_"># </span><span class="language-bash">test-vol-2</span> <span class="hljs-meta prompt_">

</span><span class="language-bash">Remove volumes</span>

docker volume create test-vol-3 docker volume rm test-vol-3 <span class="hljs-meta prompt_"># </span><span class="language-bash">test-vol-3</span>

docker volume create test-vol-4 docker volume create test-vol-5 docker volume rm test-vol-4 test-vol-5 <span class="hljs-meta prompt_"># </span><span class="language-bash">test-vol-4</span> <span class="hljs-meta prompt_"># </span><span class="language-bash">test-vol-5</span></pre></div><p id="5e89">I hope you have a clear understanding of Docker volumes and bind mounts. It will help you to persist data for your Docker projects. Happy coding!</p><h1 id="0092">Related Posts</h1><div id="26e9" class="link-block"> <a href="https://towardsdatascience.com/how-to-mount-a-directory-inside-a-docker-container-4cee379c298b"> <div> <div> <h2>How to Mount a Directory Inside a Docker Container</h2> <div><h3>Focus on writing code without worrying about environment management</h3></div> <div><p>towardsdatascience.com</p></div> </div> <div> <div style="background-image: url(https://miro.readmedium.com/v2/resize:fit:320/0*bzZMh3W3nvp_h_ye)"></div> </div> </div> </a> </div><div id="6890" class="link-block"> <a href="https://towardsdatascience.com/the-ultimate-markdown-cheat-sheet-3d3976b31a0"> <div> <div> <h2>The Ultimate Markdown Cheat Sheet</h2> <div><h3>Write an awesome README</h3></div> <div><p>towardsdatascience.com</p></div> </div> <div> <div style="background-image: url(https://miro.readmedium.com/v2/resize:fit:320/1*h4TLlisFk7XvtREAsS7C7Q.jpeg)"></div> </div> </div> </a> </div></article></body>

The Complete Guide to Docker Volumes

Learn the basics of docker volumes

Photo by Christin Hume on Unsplash

The data generated and used by containers are not persisted after we restart or remove containers. So, we can use Docker volumes and bind mounts to manage data in Docker containers to solve this issue. We can use it to persist data in a container or share data between containers. From this post, you will learn how to use Docker volumes and bind mounts in your project.

Setup

Docker uses the following types of volumes and bind mounts to persist data. For this setup, I’m using macOS.

  1. Anonymous volumes
  2. Named volumes
  3. Bind mounts

For this post, we will run a MySQL server and execute some commands. By default, MySQL will store its data files inside /var/lib/mysql directory in the container, and Docker volumes will help us to persist that data.

We have three docker-compose.yml files to demonstrate volumes and bind mounts. To start these files, you will need to use the following command.

docker compose up

Once our container is running, we can use the following commands to create a table inside our container for testing purposes.

# Access the container
docker exec -it mysql_db_1 bash
# Connect to MySQL server
mysql -uroot -proot
# Run MySQL commands
USE test_db;
SHOW TABLES;
CREATE TABLE users (
       user_id int NOT NULL AUTO_INCREMENT,
       name VARCHAR(20),
       PRIMARY KEY (user_id)
);
SHOW TABLES;

1. Anonymous volumes

If we run the following docker-compose.yml file, an anonymous volume will be created. If we restart our container, the data will be visible, but not after we remove the container. Also, it’s not accessible by other containers. It is helpful if we want to persist data temporarily. These volumes are created inside /var/lib/docker/volume local host directory.

version: '3.8'
services:
  db:
    image: mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: test_db
    ports:
      - "3306:3306"
    volumes:
      - /var/lib/mysql

As we can see, we don’t have to specify the host directory. We just need to specify the directory inside the container.

If we remove the volume instruction from the docker-compose.yml file, the container will create an anonymous volume by default because it’s specified inside the MySQL Dockerfile. So, the MySQL image ensures that we can still access the data if we don’t provide any volume information.

VOLUME /var/lib/mysql

Now, we have an anonymous volume with a random identifier.

docker volume ls
DRIVER    VOLUME NAME
local  4e679725b7179e63e8658bc157a1980f320948ab819f271fd5a44fe94c16bf23

Let’s inspect our Docker conatiner.

docker inspect mysql_db_1
.
.
.
"Mounts": [
            {
                "Type": "volume",
                "Name": "4e679725b7179e63e8658bc157a1980f320948ab819f271fd5a44fe94c16bf23",
                "Source": "/var/lib/docker/volumes/4e679725b7179e63e8658bc157a1980f320948ab819f271fd5a44fe94c16bf23/_data",
                "Destination": "/var/lib/mysql",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
.
.
.

We can use the following command to remove the container and its associated anonymous volume.

docker rm -v mysql_db_1

If we don’t remove the anonymous volume and the container together, it becomes a dangling volume.

docker rm mysql_db_1

We can list and remove all the dangling volumes using the following commands.

docker volume ls -qf dangling=true
docker volume rm $(docker volume ls -qf dangling=true)

2. Named volumes

Named volumes can persist data after we restart or remove a container. Also, it’s accessible by other containers. These volumes are created inside /var/lib/docker/volume local host directory.

version: '3.8'
services:
  db:
    image: mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: test_db
    ports:
      - "3306:3306"
    volumes:
      - db_data:/var/lib/mysql
volumes:
  db_data:

Here, the first field is a unique name of the volume on a host machine. The second part is the path in the container.

Moreover, if we remove the container using the following command, we will still have the volume, unlike anonymous volumes.

docker rm -v mysql_db_1

3. Bind mounts

Bind mounts can persist data after we restart or remove a container. As we can see, named volumes and bind mounts are the same, except the named volumes can be found under a specific host directory, and bind mounts can be in any host directory.

version: '3.8'
services:
  db:
    image: mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: test_db
    ports:
      - "3306:3306"
    volumes:
      - $PWD/data:/var/lib/mysql

Here, we are mounting a host folder. The first part is the path in the host machine. The second part is the path in the container.

Commands

Now, let’s list all the available commands for the volume instruction.

docker volume --help

Commands:
  create      Create a volume
  inspect     Display detailed information on one or more volumes
  ls          List volumes
  prune       Remove all unused local volumes
  rm          Remove one or more volumes

We can use these commands to manage anonymous volumes and named volumes.

# Creat a volume
docker volume create test-vol
# test-vol

# Inspect a volume
docker inspect test-vol
# [
#     {
#         "CreatedAt": "2021-07-17T07:23:25Z",
#         "Driver": "local",
#         "Labels": {},
#         "Mountpoint": "/var/lib/docker/volumes/test-vol/_data",
#         "Name": "test-vol",
#         "Options": {},
#         "Scope": "local"
#     }
# ]

# List all volumes
docker volume create test-vol-2
docker volume ls
# DRIVER    VOLUME NAME
# local     test-vol
# local     test-vol-2

# Remove all volumes
docker volume prune
# WARNING! This will remove all local volumes not used by at least one container.
# Are you sure you want to continue? [y/N] y
# Deleted Volumes:
# test-vol
# test-vol-2

# Remove volumes
docker volume create test-vol-3
docker volume rm test-vol-3
# test-vol-3

docker volume create test-vol-4
docker volume create test-vol-5
docker volume rm test-vol-4 test-vol-5
# test-vol-4
# test-vol-5

I hope you have a clear understanding of Docker volumes and bind mounts. It will help you to persist data for your Docker projects. Happy coding!

Related Posts

Programming
Docker
Software Engineering
DevOps
Technology
Recommended from ReadMedium