Introduction to docker Dockerfile instruction VOLUME

  • 2020-06-07 05:39:29
  • OfStack

Before introducing the VOLUME directive, let's look at the following scenario requirements:

1) The container is created based on the image. The final container file system includes the read-only layer and writable layer of the image. The data persistence of the process operation in the container is stored on the writable layer of the container. Once the container is deleted, the data is gone unless we manually back it up (or create a new image based on the container). Is it possible to have container processes persist data on the host? So even if the container is deleted, the data is still there.

2) When we were developing an web application, the development environment was local to the host, but the test environment was run on the docker container.

In this case, after I modify the files on the host (html, js, etc.), I need to resynchronize them to the container. This is obviously a bit of a hassle.

3) Multiple containers running a set of associated services, what if they want to share some data?

We can certainly think of solutions to these problems. docker itself provides a mechanism to associate a directory on the host with a directory on the container (called a mount point, or volume), where the contents under the container are in that directory, similar to the mechanism of mount under linux. This way, when we modify the contents of the directory on the host, we do not need to synchronize the container, which takes effect immediately for the container. A mount point can be Shared by multiple containers.

Now let's introduce the specific mechanism.

1. docker run command

1, run the command: docker run - name test - it - v/home/xqh/myimage: / data ubuntu/bin/bash

The -ES42en tag has one mount point /data in the container (that is, one directory in the container) and associates the contents of the /home/xqh/myimage directory on the host to /data.

Thus, operations in the /data directory in the container and /home/xqh/myimage on the host are fully synchronized in real time, since both directories are actually pointing to the host directory.

2. Run the command: docker run --name test1-ES60en-ES61en /data ubuntu /bin/bash

The -ES68en tag above only sets the container's mount point and does not specify the host directory associated with it. docker automatically binds 1 directory on the host. This can be viewed through the docker inspect command.


xqh@ubuntu:~/myimage$ docker inspect test1
[
{
  "Id": "1fd6c2c4bc545163d8c5c5b02d60052ea41900a781a82c20a8f02059cb82c30c",
.............................
  "Mounts": [
    {
      "Name": "0ab0aaf0d6ef391cb68b72bd8c43216a8f8ae9205f0ae941ef16ebe32dc9fc01",
      "Source": "/var/lib/docker/volumes/0ab0aaf0d6ef391cb68b72bd8c43216a8f8ae9205f0ae941ef16ebe32dc9fc01/_data",
      "Destination": "/data",
      "Driver": "local",
      "Mode": "",
      "RW": true
    }
  ],
...........................

Each message under Mounts above records 1 mount point on the container, the value "Destination" is the mount point of the container, and the value "Source" is the corresponding host directory.

You can see that the host directory is created automatically in this way, not to be modified on the host, but to be Shared by multiple containers.

2. Create a mount point with dockerfile

The mount point created with the -ES87en identity of the docker run command described above is valid only for the container created.

The VOLUME directive from dockerfile allows you to create a mount point in the image so that any container created through the image has a mount point.

Another difference is that mount points created through the VOLUME directive cannot specify a corresponding directory on the host and are automatically generated.


#test
FROM ubuntu
MAINTAINER hello1
VOLUME ["/data1","/data2"]

The dockfile file above specifies the two mount points /data1 and /data2 through the VOLUME directive.

When we look at the container generated from the image created by docker inspect, we see the following


  "Mounts": [
    {
      "Name": "d411f6b8f17f4418629d4e5a1ab69679dee369b39e13bb68bed77aa4a0d12d21",
      "Source": "/var/lib/docker/volumes/d411f6b8f17f4418629d4e5a1ab69679dee369b39e13bb68bed77aa4a0d12d21/_data",
      "Destination": "/data1",
      "Driver": "local",
      "Mode": "",
      "RW": true
    },
    {
      "Name": "6d3badcf47c4ac5955deda6f6ae56f4aaf1037a871275f46220c14ebd762fc36",
      "Source": "/var/lib/docker/volumes/6d3badcf47c4ac5955deda6f6ae56f4aaf1037a871275f46220c14ebd762fc36/_data",
      "Destination": "/data2",
      "Driver": "local",
      "Mode": "",
      "RW": true
    }
  ],

You can see the information for the two mount points.

3. Container Shared volume (hardpoint)


docker run --name test1 -it myimage /bin/bash

myimage in the above command is a mirror built from the previous dockerfile file. This gives the container test1 two mount points, /data1 and /data2.

Next, we create another container that can share /data1 and /data2 volumes with test1, which is used in docker run -- ES128en-ES129en tags, such as:

It can be a mirror image from a different source, such as:


docker run --name test2 -it --volumes-from test1 ubuntu /bin/bash

It can also be the mirror image of the same 1, such as:


docker run --name test3 -it --volumes-from test1 myimage /bin/bash

The above three containers test1, test2 and test3 all have /data1 and /data2 directories, and the contents of the directories are Shared. If any one container modifies the contents, other containers can get them.

4. Best practices: Data containers

If multiple containers need to share data (such as persistent databases, configuration files, or data files), consider creating a specific data container with one or more volumes.

Other containers share the volume of this data container with -- ES149en-ES150en.

Because the volume of the container essentially corresponds to the directory on the host, the data container does not need to be started.

Such as:


docker run --name dbdata myimage echo "data container"

Note: There is a volume, the data sharing between containers is convenient, but there are also many problems to be solved, such as permission control, data backup, volume deletion, etc. These are described in subsequent articles.


Related articles: