To install Docker, check out the post on installing docker.

What is secrets?

According to Docker:

... a secret is a blob of data, such as a password, SSH private key, SSL certificate, or another piece of data that should not be transmitted over a network or stored unencrypted in a Dockerfile or in your application’s source code.

For our purposes, secrets are a way to keep plain text passwords out of our Docker configuration files.

What can be stored in secrets?

You can use secrets to manage any sensitive data which a container needs at runtime but you don’t want to store in the image or in source control, such as:

  • Usernames and passwords
  • TLS certificates and keys
  • SSH keys
  • Other important data such as the name of a database or internal server
  • Generic strings or binary content (up to 500 kb in size)

Create a 1-node swarm

In order to use secrets, you will need to enable swarm services on your docker node.

docker swarm init

Example without secrets

For the two examples that follow, we will be using the official MySQL Docker image hosted on docker hub.

This first example shows how to create a stack without using secrets. Once we have this up and running, we will recreate the stack using secrets.

Let’s the MySQL deploy file to stack.yml. Notice that the credentials are in plain text — # Use root/example as user/password credentials

Default stack.yml

version: '3.1'

services:

  db:
    image: mysql
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: example

  adminer:
    image: adminer
    restart: always
    ports:
      - 8080:8080

Deploy

docker stack deploy -c stack.yml mysql-test-stack

Test

We can test that everything worked by visiting localhost:8080 in our browser and logging in using the default root/example credentials listed in the file.

PgAdminer Loging Page

Image showing a successful login

Before moving on, remove this stack:

docker stack rm mysql-test-stack

Example with secrets

Now let’s use secrets to improve the security of our stack.yml.

First, let’s generate a new password: my-secret-password (obviously, your password will be much stronger).

Create secret

echo "my-secret-password" | docker secret create mysql_root_passwd -

Note: the above command introduces security issues since our password will be stored in our bash history. You will probably want to explore more secure ways of entering your passwords into secrets, such as using ENV variables or files.

stack.yml with secrets

version: '3.1'

services:

  db:
    image: mysql
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    secrets:
      - mysql_root_passwd
    environment:
      MYSQL_ROOT_PASSWORD_FILE: /run/secrets/mysql_root_passwd

  adminer:
    image: adminer
    restart: always
    ports:
      - 8080:8080

secrets:
  mysql_root_passwd:
    external: true

Deploy

docker stack deploy -c stack.yml mysql-test-stack

Test

To verify that our new secret is working, repeat the browser login steps above by visiting localhost:8080 and using the new password.

pg adminer login using new secret

We can also see our new password from within the container. The decrypted secret is mounted into the container in an in-memory filesystem. The location of the mount point within the container defaults to /run/secrets/<secret_name> in Linux containers, or C:\ProgramData\Docker\secrets in Windows containers. You can also specify a custom location. Since I’m using Linux, the secret is mounted at /run/secrets/mysql_root_passwd in the container. We can view the decrypted secret using the following command:

docker container exec -it <CONTAINER NAME> cat /run/secrets/mysql_root_passwd
  my-secret-password

Cleanup

To destroy our stack:

docker stack rm mysql-test-stack

More Info

Conclusion

Secrets are great and pretty easy to use. Plus, no more plain text passwords. I’d call that a major win.

JohnBiz.net

Technophile and outdoor enthusiast