Docker Vault Autoloader
This is an example of how to use a docker entrypoint to automatically load keys from Hashicorp's Vault based on an a single environment variable.
This is meant as an example of my way of loading up environment variables from an external source at application runtime. This example uses Vault but it could easily be adapted to work with etcd, zookeeper, etc
Define your environment variables
Put all your environment config in the
app_env file or set a different one with the
You will use
vaultenv to get the values for the keys you want.
export PG_USER=$( vaultenv postgres/user ) export PG_PASS=$( vaultenv postgres/password ) export FOO=BAR export ANOTHER_FROM_VAULT=$( vaultenv another/from/vault )
Run the container
The entrypoint will run your command wrapped in
with_app_env which will load your
app_env first and pass off to the
CMD for the container.
docker run -e VAULT_TOKEN=123abc -e APP_ENV=production docker_vault_autoloader
Your Vault is namespaced as
Examples Vault paths:
'secret/development/postrges/password' => 'mysecurepassword' 'secret/production/application/oauth/stocktwits' => 'mystocktwitstoken'
All of your environments have the same key names
secret/development/postrges/password secret/staging/postrges/password secret/production/postrges/password secret/mobile/postrges/password
vaultenv will return the value of the given key path namespaced to the
vaultenv postgres/password => returns the value of secret/development/postgres/password
with_app_env is used by the entrypoint that sources the
$APP_ENV_FILE and passes off to the passed in command
with_app_env bash => loads the environment from $APP_ENV_FILE and then gives you a bash shell
Container Environment Variables
|VAULT_TOKEN||The vault token to use for Vault calls||YES!|
|VAULT_ADDR||The vault address to connect to||YES! (default:
|APP_ENV||The environment name to load from vault||YES (default:
|APP_ENV_FILE||The file that defines what keys to load from Vault||NO (default:
How does this work?!
with_app_env script is set as the container entrypoint. It sources the
$APP_ENV_FILE and then passes off to the
CMD. This loads the environment.
So if your
bash, when you run the container.. it actually runs this:
$APP_ENV_FILE you can use
vaultenv to get values for keys from vault.
vaultenv uses the
$VAULT_TOKEN to get the value of the keys passed to it.
vaultenv takes the
$APP_ENV and uses it to construct a path based on the key passed to it. So a call like this:
vaultenv postgres/password returns the value from vault at the location of:
Well, if you run an application that needs many secrets passed to it, you will quickly get tired of defining all the environment variables at runtime from the command line (especially if you run multiple environments that have different keys each). So I thought it would be nice to just pass in the environment and let the container fetch its keys from Vault directly at run time and load its own environment. That's what I did.