Containers Dev Ops Docker

Storing and Sharing with Docker Volumes

In Docker, you can write data on the writable layer. But the data doesn’t persist after a container shuts down. Also, it’s not easy to move the data from one container to another. Naturally, data storing and sharing is sometimes necessary between services.

Docker has three types of data mounts that can help – volumes, bind mounts, and tmpfs. Volumes store data in the host’s filesystem but it is managed by Docker. Bind mounts help store data anywhere on the host system and users can directly modify the files from the host’s own processes. The tmpfs mounts are stored in the host’s memory only. Docker volumes are the best option because they are the safest to use.

How to Use Docker Volumes

Let’s try out a hands-on example. We are going to create a few Ubuntu containers that share the same volume.

First, we want to create the volume with the following command:

$ docker volume create my-common-vol

Now we can check if the volume exists:

$ docker volume ls
 
DRIVER              VOLUME NAME
local               my-common-vol

We can further inspect the volume to check its properties:

$ docker volume inspect my-common-vol
 
[
{
  "CreatedAt": "2018-04-06T07:43:02Z",
  "Driver": "local",
  "Labels": {},
  "Mountpoint": "/var/lib/docker/volumes/my-common-vol/_data",
  "Name": "my-common-vol",
  "Options": {},
  "Scope": "local"
}
]

It’s important to remember that Mountpoint is actually inside the VM that docker is running on. So, it’s not directly accessible.

Now let’s start our first server with my-common-vol.

(Note for the docker run command, you can use the –mount and –v options to mount a volume. The syntax of the two is different. We will use the latest –mount option as it is the latest.)

$ docker run --name server1 --mount source=my-common-vol,target=/app -it ubuntu

We are mounting my-common-vol to /app folder on the server1 docker container. The above command should log you into the ubuntu server1. From the command line go to the /app folder and create a file:

[email protected]:/# cd /app
[email protected]:/app# ls
[email protected]:/app# touch created-on-server1.txt
[email protected]:/app# ls
created-on-server1.txt

So we have the file created-on-server1.txt in the /app folder.

Let’s go create a second server and mount the same my-common-vol volume to it:

$ docker run --name server2 --mount source=my-common-vol,target=/src -it ubuntu

Now we can go to the /src folder in server2, check for server1 files and create a new file:

[email protected]:/# cd /src
[email protected]:/src# ls
created-on-server1.txt
[email protected]:/src# touch created-on-server2.txt
[email protected]:/src# ls -1
created-on-server1.txt
created-on-server2.txt

In the /src folder, we see that created-on-server1.txt already exists. We add created-on-server2.txt. We can check back on server1 and see that created-on-server2.txt shows up.

Let’s start a new container server3 that will only have read-only access to the volume my-common-vol:

$ docker run --name server3 --mount source=my-common-vol,target=/test,readonly -it ubuntu

So we have created server3 with my-common-vol mounted to /test.

Let’s try to write something in /test:

[email protected]:/# cd test
[email protected]:/test# ls -1
created-on-server1.txt
created-on-server2.txt
[email protected]:/test# touch created-on-server3.txt
touch: cannot touch 'created-on-server3.txt': Read-only file system

You can see that we can’t write to my-common-vol from server3.

You can delete volumes. But you have to remove all the associated containers before you can attempt. Otherwise, you’ll get an error like this:

$ docker volume rm my-common-vol
 
Error response from daemon: unable to remove volume: remove my-common-vol:
volume is in use - [1312ea07405528bc65736f56692c06f04280779fd283a81f59f8477f28ae35ba,
77cd51945461fa03f572ea6830a98a16ece47b4f840c2edfc2955c7c9a6d69d2,
a6620da1eea1a39d64f3acdf82b6d70309ee2f8d1f2c6b5d9c98252d5792ea59]

In our case, we can remove the containers and the volume like this:

$ docker container rm server1
 
$ docker container rm server2
 
$ docker container rm server3
 
$ docker volume rm my-common-vol

Also, if you want to mount multiple volumes, the “docker run” command’s –mount option allows that too.

Further Study:

About the author

Zak H

Zak H

Zak H. lives in Los Angeles. He enjoys the California sunshine and loves working in emerging technologies and writing about Linux and DevOps topics.