12 Docker Volumes - dchantzis/sfh-docker-in-development-part-1 GitHub Wiki

Source: https://serversforhackers.com/c/div-docker-volumes

We will cover Docker volumes and make sure we have set our docker-compose.yml file correctly to use our created volumes.

The following command will list the existing Volumes:

docker volume ls

The listed Volume is from the mysql Container as it was created using a Dockerfile that is listing a Volume. We can view the used Dockerfile at https://github.com/docker-library/mysql/blob/d284e15821ac64b6eda1b146775bf4b6f4844077/5.7/Dockerfile:

FROM debian:buster-slim
...
.
.
.
...
VOLUME /var/lib/mysql
...

This will tell Docker to create a Volume and share it in the /var/lib/mysql directory in the Container.


We can kill our mysql Container:

docker kill <CONTAINER_ID>

and check that it's gone:

docker ps -a

If we check our Volumes we will see that the previous Volume is gone and with it our database data:

docker volume ls

We can now create a new volume like so:

docker volume create mydata

and now we can:

docker run -d --rm --name=mysql -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=homestead -e MYSQL_USER=homestead -e MYSQL_PASSWORD=secret --network=appnet -v mydata:/var/lib/mysql mysql:5.7
  • -v Specify the location to share the mydata Volume within our Container and bind it to "/var/lib/mysql" : -v mydata:/var/lib/mysql

We can now inspect the mysql Container:

docker inspect mysql

and we can see that under "Mounts" we have a Volume named "mydata" mounted to that Container successfully.


Now we need to run the migrations again in the app Container (since we lost all the data when we initially killed the previous mydata Container and then recreated it):

docker exec -it -w /var/www/html app php artisan migrate

We can now run the following to view all the database tables of the database name "homestead" inside the mysql Container, by connecting to mysql (using the credentials with -u and -p) and executing a command (with -e):

docker exec -it mysql mysql -u root -p -e "USE homestead; SHOW TABLES;"

Now we can kill the running Container mysql:

docker kill <CONTAINER_ID>

and check our Volumes:

docker volume ls

and we can see that our Volume mydata still exists.

Now we can run ("spin out") a totally new instance of mysql and connect it to the same existing Volume mydata with our database data.

docker run -d --name=mysql --network=appnet -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=homestead -e MYSQL_USER=homestead -e MYSQL_PASSWORD=secret --network=appnet -v mydata:/var/lib/mysql mysql:5.7

Don't forget to specify the following:

  • --name The hostnname
  • --network The network

Now we can see our database data (that were created from the laravel migrations), like so:

docker exec -it mysql mysql -u root -p -e "USE homestead; SHOW TABLES;"

We can create and destroy MySQL containers as much as we want. As long as we share the mydata volume, the database data will persist (assuming, of course, we don't delete the volume via docker volume rm mydata!)