Today we will use Docker Secrets, more specifically store our MySQL Passwords in Secrets, which will be passed to our containers, so that we don’t use clear text passwords in our Compose files.
What is Docker Secrets:
In Docker, Docker Secrets are encrypted during transit and at rest in a Docker Swarm Cluster. The great thing about Docker Secrets is that you can manage these secrets from a central place, and the fact that it encrypts the data and transfers the data securely to the containers that needs the secrets. So you authorize which containers needs access to these secrets.
So instead of setting the MySQL Root Passwords in clear text, you will create the secrets, then in your docker-compose file, you will reference the secret name.
Deploy MySQL with Docker Secrets
We will deploy a Stack that contains MySQL and Adminer (WebUI for MySQL).
We will make the MySQL Service Persistent by setting a constraint to only run on the Manager node, as we will create the volume path on the host, and then map the host to the container so that the container can have persistent data. We will also create secrets for our MySQL Service so that we dont expose any plaintext passwords in our compose file.
As we specified our secrets and networks as external resources, it needs to exist before we deploy our stack. We also need to create the directory for our mysql data, as the data will be mapped from our host to our container.
$ docker secret ls
ID NAME CREATED UPDATED
jzhrwyxkiqt8v81ow0xjktqnw db_root_password 12 seconds ago 12 seconds ago
plr6rbrqkqy7oplrd21pja3ol db_dba_password 4 seconds ago 4 seconds ago
Inspect the secret, so that we can see that theres not value exposed:
$ docker exec -it $(docker ps -f name=apps_db -q) mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 5.7.20 MySQL Community Server (GPL)Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h'for help. Type '\c' to clear the current input statement.
mysql> show databases;+--------------------+
| Database |+--------------------+
| information_schema || mydb || mysql || performance_schema || sys |+--------------------+
5 rows in set(0.00 sec)
As we have deployed adminer, you can access the Adminer WebUI on the Host’s IP and the Defined Port.
Testing Data Persistance:
12345678910111213141516171819202122
$ docker exec -it $(docker ps -f name=apps_db -q) mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
mysql> create database ruan;Query OK, 1 row affected (0.00 sec)mysql> show databases;+--------------------+
| Database |+--------------------+
| information_schema || mydb || mysql || performance_schema || ruan || sys |+--------------------+
6 rows in set(0.00 sec)mysql> exit;Bye
Verify the hostname of our container, before we kill the container:
Verify the status of the MySQL Service, as we can see the service count is 0, so the container was succesfully killed.
123
$ docker service ls -f name=apps_db
ID NAME MODE REPLICAS IMAGE PORTS
nzf96q05fktm apps_db replicated 0/1 mysql:latest *:3306->3306/tcp
After waiting for a couple of seconds, we can see the service is in service again, then check the hostname so that we can confirm that its a new container:
123456
$ docker service ls -f name=apps_db
ID NAME MODE REPLICAS IMAGE PORTS
nzf96q05fktm apps_db replicated 1/1 mysql:latest *:3306->3306/tcp
$ docker exec -it $(docker ps -f name=apps_db -q) hostname
95c15c89f891
Logong to MySQL again and verify if our perviously created database is still there:
12345678910111213141516
$ docker exec -it $(docker ps -f name=apps_db -q) mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
mysql> show databases;+--------------------+
| Database |+--------------------+
| information_schema || mydb || mysql || performance_schema || ruan || sys |+--------------------+
6 rows in set(0.01 sec)
By design docker is stateless, but as we mapped the host’s path to the container our data is persistent. As we have set a constraint so that the container must only spin up on this node, the container will always have access to the data path.