Preface
When we start a container, all kinds of data are stored in the container. Once the docker rm command is executed accidentally, the container will be deleted and the data will be lost. The data generated by the docker container must be persisted in the production environment, and the problem of data sharing among multiple containers will also be involved. To solve these problems, we can use docker's data volume technology.
What is a data volume
Data Volume (Data Volumes) is a special directory that can be used by containers to map the data inside the container directly to the host machine. Even if the container is accidentally deleted, the data generated by the container is stored on the host machine. For example, I can map the container path **/usr/local/data** to the host/soft/docker/data path, as shown in the following figure:
Data volume technology enables us to persist container data and share data between containers.
Create Data Volume
docker provides volume commands for managing data volumes, and we can use help to see how the command works:
[root@VM-0-10-centos ~]# docker volume --help Usage: docker volume COMMAND Manage volumes 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 Run 'docker volume COMMAND --help' for more information on a command.
Using the create command, you can create a container volume as follows:
[root@VM-0-10-centos ~]# docker volume create my-volume my-volume
Use the ls command to view all volumes that exist in the current container:
[root@VM-0-10-centos ~]# docker volume ls DRIVER VOLUME NAME local my-volume
The volume created by the create command defaults to the host **/var/lib/docker/volumes** path and can be viewed using the **tree** command:
[root@VM-0-10-centos volumes]# tree /var/lib/docker/volumes/ /var/lib/docker/volumes/ |-- backingFsBlockDev |-- metadata.db `-- my-volume `-- _data 2 directories, 2 files
Use the inspect command to view data volume details:
[root@VM-0-10-centos volumes]# docker volume inspect my-volume [ { "CreatedAt": "2021-12-25T21:22:14+08:00", "Driver": "local", "Labels": {}, "Mountpoint": "/var/lib/docker/volumes/my-volume/_data", "Name": "my-volume", "Options": {}, "Scope": "local" } ]
Use the prune command to clean up unused containers:
[root@VM-0-10-centos 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: my-volume Total reclaimed space: 0B
Use the rm command to delete container volumes:
- Create Container
## Create Container Volume [root@VM-0-10-centos volumes]# docker volume create my-volume my-volume ## List all container volumes [root@VM-0-10-centos volumes]# docker volume ls DRIVER VOLUME NAME local my-volume
Use -q to list only container volume names:
[root@VM-0-10-centos volumes]# docker volume ls -q my-volume
Delete a single container volume:
[root@VM-0-10-centos volumes]# docker volume rm my-volume my-volume
Bulk Delete All Container Volumes
[root@VM-0-10-centos volumes]# docker volume create my-volume my-volume ## Delete all container volumes [root@VM-0-10-centos volumes]# docker volume ls -q | xargs docker volume rm my-volume
Bind data volume
In addition to using the volume command to manage data volumes, we can also create container volumes and map them to host paths when creating containers. First, we download a mirror of nginx to demonstrate the binding of container volumes:
- Download nginx image
[root@VM-0-10-centos volumes]# docker pull nginx Using default tag: latest latest: Pulling from library/nginx a2abf6c4d29d: Pull complete f3409a9a9e73: Pull complete 9919a6cbae9c: Pull complete fc1ce43285d7: Pull complete 1f01ab499216: Pull complete 13cfaf79ff6d: Pull complete Digest: sha256:366e9f1ddebdb844044c2fafd13b75271a9f620819370f8971220c2b330a9254 Status: Downloaded newer image for nginx:latest docker.io/library/nginx:latest
- Run the mirror and mount the data volume
You can map host paths to container contents when creating containers, such as HTML directories mapping nginx containers, such as mapping host paths/soft/data/docker/html and/soft/nginx/html
[root@VM-0-10-centos html]# docker run -d --name nginx -P -v /soft/data/docker/html:/soft/nginx/html nginx e0c7ed8c9999b4121c3c3a62eb23f7579a145ecbbc3885ecfe461fad1a8842cc
Create test.html:
vim test.html ## Add the following: <<html> <head> <script type="text/javascript"> function alertIndex() { var x=document.getElementById("mySelect").selectedIndex; var y=document.getElementsByTagName("option"); alert(y[x].text + " has the index of: " + y[x].index); } </script> </head> <body> <form> Select your favorite fruit: <select id="mySelect"> <option>Apple</option> <option>Orange</option> <option>Pineapple</option> <option>Banana</option> </select> <br /> <br /> <input type="button" onclick="alertIndex()" value="Show index of the chosen fruit"> </form> </body> </html>
You can see that there is a test under the current path. Html:
[root@VM-0-10-centos html]# ll total 4 -rw-r--r-- 1 root root 555 Dec 26 20:03 test.html [root@VM-0-10-centos html]# pwd /soft/data/docker/html
Enter the container to view:
[root@VM-0-10-centos html]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e0c7ed8c9999 nginx "/docker-entrypoint...." 46 minutes ago Up 46 minutes 0.0.0.0:49160->80/tcp, :::49160->80/tcp nginx
When you enter the container, you can see the html file you just created on the host, and it also exists on the appropriate path to the container.
[root@VM-0-10-centos html]# docker exec -it nginx /bin/bash ## You can see / soft/nginx/html root@e0c7ed8c9999:/# cd /soft/nginx/html root@e0c7ed8c9999:/soft/nginx/html# ls -lsa total 12 4 drwxr-xr-x 2 root root 4096 Dec 26 12:03 . 4 drwxr-xr-x 3 root root 4096 Dec 26 11:19 .. 4 -rw-r--r-- 1 root root 555 Dec 26 12:03 test.html
The test you just created. Copy HTML to ****
root@e0c7ed8c9999:/soft/nginx/html# cp test.html /usr/share/nginx/html/
Then access it in the browser as follows:
The command to mount a container volume on top is -v, or you can use the -mount command:
[root@VM-0-10-centos ~]# docker run -d --name my-nginx -P --mount type=bind,source=/soft/data/docker/my-nginx,destination=/soft/container/nginx nginx docker: Error response from daemon: invalid mount config for type "bind": bind source path does not exist: /soft/data/docker/my-nginx. See 'docker run --help'.
It is important to note that host mount paths must exist or errors will occur as shown above:
[root@VM-0-10-centos ~]# mkdir -p /soft/data/docker/my-nginx [root@VM-0-10-centos ~]# docker run -d --name my-nginx -P --mount type=bind,source=/soft/data/docker/my-nginx,destination=/soft/container/nginx nginx bdf701f0a0835089e408d750381684f74ab8393f708cfc0678c4b6b3e21e5254
Log in to the nginx container to see if the path mapping exists.
[root@VM-0-10-centos ~]# docker exec -it my-nginx /bin/bash root@bdf701f0a083:/# cd /soft/container/nginx/ root@bdf701f0a083:/soft/container/nginx# ls -lsa total 8 4 drwxr-xr-x 2 root root 4096 Dec 26 14:23 . 4 drwxr-xr-x 3 root root 4096 Dec 26 14:23 ..
Create a document in a container:
root@bdf701f0a083:/soft/container/nginx# echo "test message" > haha.txt root@bdf701f0a083:/soft/container/nginx# ls -lsa total 12 4 drwxr-xr-x 2 root root 4096 Dec 26 14:29 . 4 drwxr-xr-x 3 root root 4096 Dec 26 14:23 .. 4 -rw-r--r-- 1 root root 13 Dec 26 14:29 haha.txt
Host view text content:
[root@VM-0-10-centos ~]# cat /soft/data/docker/my-nginx/haha.txt test message
It is important to note that the host path must be absolute. If you use --mount, you need to determine that the mounted path exists or you will encounter errors. Docker can also specify read and write permissions for the host directory when mounting it. The default permission is read and write (rw), or the user can specify read-only permissions, that is, ro:
docker run -d --name my-nginx -P --mount type=bind,source=/soft/data/docker/my-nginx:ro,destination=/soft/container/nginx nginx
With ro privileges added, the container can only read mounted paths and cannot modify data in the data volume.
Create a shared data volume container
Generally, in development, you will encounter multiple containers sharing the same batch of data directly. You can use data volume containers. Note that the data volume containers themselves are also containers. Here are three centos mirrors to illustrate the use of container data volumes:
- Download centos image:
[root@VM-0-10-centos ~]# docker pull centos:7 7: Pulling from library/centos 2d473b07cdd5: Pull complete Digest: sha256:9d4bcbbb213dfd745b58be38b13b996ebb5ac315fe75711bd618426a630e0987 Status: Downloaded newer image for centos:7 docker.io/library/centos:7
Create a data volume container
[root@VM-0-10-centos ~]# docker run -it -v /dir --name dir centos:7
Create a new file in the dir directory and enter:
[root@8d3d2d3d6edf /]# echo "Hi I am GalenGao" > /dir/test.txt
Exit the container with crtl + p + q, and mount the container volume with two new containers centos1 and centos2.
Create container centos1 to see if there is a corresponding container volume directory:
[root@VM-0-10-centos volumes]# docker run -it --name centos1 --volumes-from dir centos:7
You can clearly see that the corresponding dir directory exists and test. The TXT document also exists, at this time we append some text:
[root@6cc32c0aeb05 dir]# echo "it's a message from centos1" >> test.txt
Create the container centos2 to view the corresponding text:
[root@VM-0-10-centos volumes]# docker run -it --name centos2 --volumes-from dir centos:7 [root@a1db0373c9c8 /]# cat /dir/test.txt Hi I am GalenGao it's a message from centos1
From the above demonstration, you can see that the centos1 and centos2 containers output files in the same directory, which can be viewed in their respective directories, for data sharing purposes.
Delete shared data volume
Running containers are deleted without affecting their true host content. If you want to delete containers at the same time you need to delete their data volumes, you need to specify the corresponding container data volumes in the last container where the real host is mounted. For example, by deleting the container data volume you just created, you can use the docker rm-v command to specify that the associated container is also deleted.
[root@VM-0-10-centos volumes]# docker rm -f dir -v /dir /dir Error response from daemon: removal of container dir is already in progress [root@VM-0-10-centos volumes]# docker ps