Docker 1.13 includes in Swarm the new concept of secrets management.
As we know, we need Swarm mode to use secrets. When we initialize a Swarm, Swarm generates some secrets for us:
$ docker swarm init
Docker 1.13 adds the secrets management with a new command, secret, with the purpose to handle them efficiently. Secret subcommands are created, ls, to inspect and rm.
Let's create our first secret. The secret create
sub-command takes a secret from the standard input. So, we need to type in our secret, and then press Ctrl+D to save the content. Be careful to not hit the Enter key. We need only 1234
not 1234
as our password, for example:
$ docker secret create password 1234
Then press Ctrl+D twice to close the standard input.
We can check if there is a secret called password:
$ docker secret ls ID NAME CREATED UPDATED 16blafexuvrv2hgznrjitj93s password 25 seconds ago 25 seconds ago uxep4enknneoevvqatstouec2 test-pass 18 minutes ago 18 minutes ago
How does this work? The content of secret can be bound to a service by passing the secret option when we create a new service. The secret will be a file in the /run/secrets/
directory. In our case, we'll have /run/secrets/password
containing the string 1234
.
Secrets are designed to replace the abuse of environment variables. For example, in the case of a MySQL or MariaDB container, its root password should be set as a secret instead of passing it as a plaintext via an environment variable.
We will show a small hack to make MariaDB support the new Swarm secrets, starting from the following entrypoint.sh
:
$ wget https://raw.githubusercontent.com/docker-
library/mariadb/2538af1bad7f05ac2c23dc6eb35e8cba6356fc43/10.1/docker-entrypoint.sh
We put this line into this script, around line 56, before the check of MYSQL_ROOT_PASSWORD
.
# check secret file. if exist, override if [ -f "/run/secrets/mysql-root-password" ]; then MYSQL_ROOT_PASSWORD=$(cat /run/secrets/mysql-root-password) fi
This code checks if there exists /run/secrets/mysql-root-password
. If so, it assigns the secret to the environment variable MYSQL_ROOT_PASSWORD
.
After this we can prepare a Dockerfile to override the MariaDB's default docker-entrypoint.sh
.
FROM mariadb:10.1.19 RUN unlink /docker-entrypoint.sh COPY docker-entrypoint.sh /usr/local/bin/ RUN chmod +x /usr/local/bin/docker-entrypoint.sh RUN ln -s usr/local/bin/docker-entrypoint.sh /
We then build the new image.
$ docker build -t chanwit/mariadb:10.1.19 .
Recalled that we have a secret named password, we have an image which allows us to set the root password from the secret file /run/secrets/mysql-root-password
. So, the image expects a different file name under /run/secrets
. With this we can use the secret with full option (source=password
, target=mysql-root-password
) to make a Swarm service work. For example, we can now start a new mysql
Swarm service from this MariaDB image:
$ docker network create -d overlay dbnet lsc7prijmvg7sj6412b1jnsot $ docker service create --name mysql --secret source=password,target=mysql-root-password --network dbnet chanwit/mariadb:10.1.19
To see if our secret works, we can start an instance of PHPMyAdmin on the same overlay network. Don't forget to link these services together by passing -e PMA_HOST=mysql
to the myadmin
service.
$ docker service create --name myadmin --network dbnet --publish 8080:80 -e PMA_HOST=mysql phpmyadmin/phpmyadmin
Then you can open your browser to http://127.0.0.1:8080
and log in to PHPMyAdmin
as root with 1234
as the password, which we provided through a Docker secret.