Running Docker in Production: Managing Application Secrets

With modern microservice architecture application is split into separated services and they are each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API. They may share also some other sensitive data for example passwords and certificates. The challenge is how and where to store this data in order to gain maximum portability.

If you are following the twelve-factor app paradigm, it suggests storing application configuration in environment variables. The same method goes for containerized applications, where the environment variables are the de-facto way to pass config variables to applications. With Docker, environment variables can be described in docker-compose.yml or dedicated environment files that are referenced in the YAML file. Conceptually, the docker-compose.yml file is a blueprint that people should be able to share, so those sensitive config variables can not be stored in version control system. There must be a better place where those environment variables can be stored securely, so that applications can use them.

Kontena Vault provides a perfect solution to this challenge. Kontena Vault is a secure key/value storage that can be used to manage secrets in Kontena. It secures, stores, and tightly controls access to sensitive data you want to use with your containerized applications.

After the data is stored in Kontena Vault they can be referenced in kontena.yml. Kontena will expose them to running services in environment variables. Vault secrets are shared on a grid level, so all the services on the same grid can use them. Kontena will also keep track of Vault read operations in the audit log making it very transparent who is handling the sensitive data.

How to Use Kontena Vault

The following example will demonstrate how to store database root password securely for Wordpress blog. We will store MySQL root password to Kontena Vault and use that for MariaDB and Wordpress services.

Secrets are stored in Kontena via Kontena CLI commands:

$ kontena vault write <name> <value>

So we can save the Vault entry MYSQL_ADMIN_PASSWORD with the following command.

$ kontena vault write MYSQL_ADMIN_PASSWORD V3rySecretP2ssw0rd

We can reference that Vault entry in kontena.yml by describing Vault entries in secrets section by giving name and environment variable where Kontena will expose the entry value. For example:

secrets:  
    - secret: <SECRET_NAME>
      name: <ENVIRONMENT_VARIABLE>
      type: env

Great. Now we can describe the whole application and expose Kontena Vault entry to wordpress and mysql services :

wordpress:  
  image: wordpress:4.1
  stateful: true
  ports:
    - 80:80
  links:
    - mysql:wordpress-mysql
  environment:
    - WORDPRESS_DB_HOST=%{project}-mysql.kontena.local
    - WORDPRESS_DB_USER=root
  secrets:
    - secret: MYSQL_ADMIN_PASSWORD
      name: WORDPRESS_DB_PASSWORD
      type: env

mysql:  
  image: mariadb:5.5
  stateful: true
  secrets:
    - secret: MYSQL_ADMIN_PASSWORD
      name: MYSQL_ROOT_PASSWORD
      type: env

Now when we deploy the application with $ kontena app deploy, Kontena will expose MYSQL_ADMIN_PASSWORD Vault entry to given enviroment variables and application will start and run as expected.

And what is the best, we can store kontena.yml in a version control system without leaking secret passwords.

About Kontena

Kontena is a new open source Docker platform including orchestration, service discovery, overlay networking and all the tools required to run your containerized workloads. Kontena is built to maximize developer happiness. It works on any cloud, it's easy to setup and super simple to use. Give it a try! If you like it, please star it on Github and follow us on Twitter. We hope to see you again!