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!
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-updepends_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
USE somedatabase;
SHOW TABLES;
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;
exit;
and remove the containers:
docker-compose stop
docker-compose rm
So, how can we make data persistent, even we remove the containers? With volumes and a host-mounted data directory, for example.
mkdir data
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
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 🎉