
How to docker: Understand anonymous and named volumes
Prerequisites
Docker Volumes And Logging
How to docker : Learn why volumes came into beingmedium.com
Let us look at a practical use case of deploying a database and persisting data into the host.
Let’s see how we would go about it
First let’s take a look at mysql Dockerfile, you will notice it already uses volume for /var/lib/mysql
VOLUME /var/lib/mysql //from the dockerfile
Let’s see if it works.
Pull mysql image from docker hub.
docker pull mysql
2. Create a container from mysql image
docker run --name myDatabase -e MYSQL_ROOT_PASSWORD=password -d mysql
//Output64bc9a755e8e85a2f9902805a7cd24b80c33804503491958d12abac5b2f0001b
For now ignore -e
flag MYSQL_ROOT_PASSWORD
. We will cover it later.
We are just telling mysql here what password to use for root user.
3. Enter the container and start mysql
docker exec -it 64b mysql -u root -p
It will prompt for a password. Use the same one you used to run the container.
We have successfully started a mysql container:)

Populating the database
For the purpose of this tutorial, let us add data directly to the database.
Note: This would not be a case while running an app in production. Ideally, it will get all it’s data from the back-end.
Let’s create a table called users and add a few rows in it.
mysql> create database app;Query OK, 1 row affected (0.04 sec)
mysql> use app;Database changed
mysql> create table users(id int not null auto_increment primary key, name varchar(100), username varchar(100), age int);Query OK, 0 rows affected (0.10 sec)
mysql> insert into users(name, username, age) values ("John Doe", "jdoe22", 22);Query OK, 1 row affected (0.02 sec)
mysql> insert into users(name, username, age) values ("Hannibal Lecture", "maneater69", 45);Query OK, 1 row affected (0.04 sec)
Let us view the records in users now
mysql> select * from users;+----+------------------+------------+------+| id | name | username | age |+----+------------------+------------+------+| 1 | John Doe | jdoe22 | 22 || 2 | Hannibal Lecture | maneater69 | 45 |+----+------------------+------------+------+2 rows in set (0.00 sec)
We have our data in place now.
Launching another SQL container
Mysql containers use docker volumes. So the new container should have access to the persisted data.
If you start a second container on the same machine, ideally it should bind to the same volume.
Let’s try it out and see if that really happens.
docker run --name myDatabase2 -e MYSQL_ROOT_PASSWORD=password -d mysql
//Outpute905312e2a6029a95484116715826b635315e868d1014ea6ef1099dbb9cab97a
Let us see if we see the same data as both the containers share the same volume as you saw in Dockerfile, which is VOLUME /var/lib/mysql
docker exec -it e90 mysql -u root -p
//Run the following commands once you established a mysql sessionmysql> use app;ERROR 1049 (42000): Unknown database 'app'
So what is happening here? We are also using volumes so why are we not seeing the data?
Anonymous Volumes
Let us confirm both the containers are using volumes by running docker inspect <container-id>
docker inspect e90
//Output..."Mounts": [ { "Type": "volume", "Name": "86d582b1e613f30b1fff84f7cdaf78deb11bead8bff0b684d65fd2c46c56d00f", "Source": "/var/lib/docker/volumes/86d582b1e613f30b1fff84f7cdaf78deb11bead8bff0b684d65fd2c46c56d00f/_data", "Destination": "/var/lib/mysql", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" } ],...
docker inspect 64b
//Output..."Mounts": [ { "Type": "volume", "Name": "6709ef1fc6804af4a543f29d8cc71c204811d82182b7de0ace2a742be186fbe3", "Source": "/var/lib/docker/volumes/6709ef1fc6804af4a543f29d8cc71c204811d82182b7de0ace2a742be186fbe3/_data", "Destination": "/var/lib/mysql", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" } ],...
The key thing to note here is even though the destination directories same, the source directories are different.
Although the volume points to the same folder inside the container, on the host system, since we’ve not explicitly assigned a folder, it creates a unique folder in the docker volumes directory.

Let’s verify these two volumes are different by running the following command
docker volume ls
//OutputDRIVER VOLUME NAMElocal 86d582b1e613f30b1fff84f7cdaf78deb11bead8bff0b684d65fd2c46c56d00flocal 6709ef1fc6804af4a543f29d8cc71c204811d82182b7de0ace2a742be186fbe3
These are anonymous volumes and are created and managed by docker.
Note : They are stored here /var/lib/docker/volumes
So how do we ensure all our mysql containers have access to the same data?
Named Volumes
These are exactly same as anonymous volumes just with a user friendly identifier.
Named volumes are also created and managed by docker.
Let us look at how they solve our problem.

Create a mysql container with named volume
docker run --name myDatabaseWithVolume -e MYSQL_ROOT_PASSWORD=password -d -v appdata:/var/lib/mysql mysql
//Output59ab826cc183520e893ab115624923d1da4e2267dc59884849d576771a3027ec
Note : appdata is a user friendly identifier we assign to a volume.
2. Enter the container and populate it the same way we did before.
3. Firing a select command should have a similar output
mysql> select * from users;+----+------------------+------------+------+| id | name | username | age |+----+------------------+------------+------+| 1 | John Doe | jdoe22 | 22 || 2 | Hannibal Lecture | maneater69 | 45 |+----+------------------+------------+------+2 rows in set (0.00 sec)
4. Stop the container and create a new one.
docker container stop 59a
docker run --name myDatabaseWithVolume2 -e MYSQL_ROOT_PASSWORD=password -d -v appdata:/var/lib/mysql mysql
//Outputb2dcf30288f8d90729903930b39ca025e42f9591899ed368ff78f846b02b90f8
5.Enter the container and fire the following sql command.
docker exec -it b2d mysql -u root -p
mysql> use app;Reading table information for completion of table and column namesYou can turn off this feature to get a quicker startup with -A
Database changedmysql> select * from users;+----+------------------+------------+------+| id | name | username | age |+----+------------------+------------+------+| 1 | John Doe | jdoe22 | 22 || 2 | Hannibal Lecture | maneater69 | 45 |+----+------------------+------------+------+2 rows in set (0.00 sec)
We are able to successfully read the data created in a different container with zero configuration.
This is exactly how named volumes help us.
Note : You can also see all named volumes and anonymous volumes.
docker volume ls
//OutputDRIVER VOLUME NAMElocal 86d582b1e613f30b1fff84f7cdaf78deb11bead8bff0b684d65fd2c46c56d00flocal 6709ef1fc6804af4a543f29d8cc71c204811d82182b7de0ace2a742be186fbe3local appdata
Notice the last volume, it’s name is user friendly instead string of random characters.
Congratulations !! you have learned yet another docker concept : volumes.
Happy Learning:)

Follow us on Twitter 🐦 and Facebook 👥 and Instagram 📷 and join our Facebook and Linkedin Groups 💬.
To join our community Slack team chat 🗣️ read our weekly Faun topics 🗞️, and connect with the community 📣 click here⬇
