Skip to Content
CoursesLearn DockerDirectory Mounting with Docker-Compose

Data Persistence and Docker Compose

Have you ever wondered, what happens if you shut down the containers - what will happen with the precious content of the Database?

Or … where does the Data even go?! šŸ¤”

In this lecture we’re going to explore just that: Different options for volume mounting inside Docker-Compose!

View the Full Course Now 

Databases and Data Persistence in Host-Volume Mounted Directories in Docker Step by Step

In the previous example we were spinning up our database with our web-app. But docker containers are ephemeral. This means they are losing all data once removed and re-started. So, somehow, we must find a way to make data persistent if we want to keep it. Use this docker-compose.yml file:

version: '3' services: db: image: mysql:latest restart: always container_name: myphpapp-db environment: MYSQL_ROOT_PASSWORD: somepass MYSQL_DATABASE: somedatabase dbclient: image: mysql:latest depends_on: - db command: mysql -uroot -psomepass -hdb
  • MYSQL_DATABASE will create an empty database with the name ā€œsomedatabaseā€ at first spin-up
  • depends_on waits for the container to start on the other containers
command

If you look at the command for the dbclient service, you see that we wrote mysql -uroot -psomepass -hdb. There is no space between -u and the username root, -p and the password and -h and the host.

Start the Containers

Let’s run the containers and see what will happen:

Run the command:

docker-compose up -d
  • starts both containers in detached mode (-d)
docker-compose ps
  • will show the ā€œdbā€ running, while the other one stopped
docker-compose run --rm dbclient
  • should connect to the ā€œdbā€ and open a mariadb shell Enter the following SQL queries:
USE somedatabase; SHOW TABLES;

Observe that it’s empty!

CREATE TABLE mytable (id INT); SHOW TABLES;

Now you have one table in your database, which we created.

mysql> SHOW TABLES; +------------------------+ | Tables_in_somedatabase | +------------------------+ | mytable | +------------------------+ 1 row in set (0.00 sec)

Exit the console with

exit;

Now stop the container:

docker-compose stop

and remove the containers

docker-compose rm
  • removes all (not running) containers from docker-compose
Remove Containers

You can also stop and remove all containers by doing docker-compose down

Let’s re-run everything and see if data persisted:

docker-compose up -d
  • Re-Run the containers based on the images
  • Only the database container is running

Login to the mysql shell again:

docker-compose run --rm dbclient

Then run again:

USE somedatabase; SHOW TABLES;

Observe it’s empty again. But why?! And what can we do about it?!

exit;

and remove the containers:

docker-compose stop docker-compose rm
  • Stop and remove the containers before we continue

So, how can we make data persistent, even we remove the containers? With volumes and a host-mounted data directory, for example.

mkdir data
  • Create a new ā€œdataā€ directory on the host

And add a volumes key to your docker-compose.yml file:

version: '3' services: db: image: mysql:latest restart: always container_name: myphpapp-db environment: MYSQL_ROOT_PASSWORD: somepass MYSQL_DATABASE: somedatabase volumes: - ./data:/var/lib/mysql dbclient: image: mysql:latest depends_on: - db command: mysql -uroot -psomepass -hdb

Now start the db service:

docker-compose db -d up
  • Observe the data directory, it gets populated with data

We can also enter the container now.

docker-compose run --rm dbclient

Recreate the table:

USE somedatabase; SHOW TABLES;

Then create the table, because it is empty right now.

CREATE TABLE mytable (id INT); SHOW TABLES;

And then exit and stop and remove the container:

exit;
docker-compose stop docker-compose rm

Now spin up the db container again:

docker-compose up -d db

Then login to the mysql client:

docker-compose run --rm dbclient
USE somedatabase; SHOW TABLES;

Observe the database is now persistent. But maybe writing on the host into a directory is not the best solution in this case. Maybe a named volume would be better?! Oh wait there’s a lecture about that in the next step šŸŽ‰

Last updated on