Configuration and Config Vars
Last updated 29 September 2015
Table of Contents
A given codebase may have numerous deployments: a production site, a staging site, and any number of local environments maintained by each developer. An open source app may have hundreds or thousands of deployments.
Although all running the same code, each of these deploys have environment-specific configurations. One example would be credentials for an external service, such as Amazon S3. Developers may share one S3 account, while the staging site and production sites each have their own keys.
The traditional approach for handling such config vars is to put them under source - in a properties file of some sort. This is an error-prone process, and is especially complicated for open source apps which often have to maintain separate (and private) branches with app-specific configurations.
A better solution is to use environment variables, and keep the keys out of the code. On a traditional host or working locally you can set environment vars in your
bashrc file. On Heroku, you use config vars.
Setting up config vars for a deployed application
Use the Heroku CLI’s
config:unset to manage your config vars:
Previous versions of the Heroku Toolbelt used
$ heroku config:set GITHUB_USERNAME=joesmith Adding config vars and restarting myapp... done, v12 GITHUB_USERNAME: joesmith $ heroku config GITHUB_USERNAME: joesmith OTHER_VAR: production $ heroku config:get GITHUB_USERNAME joesmith $ heroku config:unset GITHUB_USERNAME Unsetting GITHUB_USERNAME and restarting myapp... done, v13
You can also edit config vars on your app’s settings tab on Dashboard:
Heroku manifests these config vars as environment variables to the application. These environment variables are persistent – they will remain in place across deploys and app restarts – so unless you need to change values, you only need to set them once.
Whenever you set or remove a config var, your app will be restarted.
Config var data (the collection of all keys and values) is limited to 16kb for each app.
Add some config vars for your S3 account keys:
$ cd myapp $ heroku config:set S3_KEY=8N029N81 S3_SECRET=9s83109d3+583493190 Setting config vars and restarting myapp... done, v14 S3_KEY: 8N029N81 S3_SECRET: 9s83109d3+583493190
Set up your code to read the vars at runtime. For example, in Ruby you access the environment variables using the
ENV['KEY'] pattern - so now you can write an initializer like so:
AWS::S3::Base.establish_connection!( :access_key_id => ENV['S3_KEY'], :secret_access_key => ENV['S3_SECRET'] )
In Java, you can access it through calls to
System.getenv('key'), like so:
S3Handler = new S3Handler(System.getenv("S3_KEY"), System.getenv("S3_SECRET"))
s3 = S3Client(os.environ['S3_KEY'], os.environ['S3_SECRET'])
Now, upon deploying to Heroku, the app will use the keys set in the config.
Use the Heroku Local command-line tool to run your app locally. For more information see the Heroku Local article.
Production and development modes
Many languages and frameworks support a development mode. This typically enables more debugging, as well as dynamic reloading or recompilation of changed source files.
For example, in a Ruby environment you could set a
RACK_ENV config var to
development to enable such a mode.
It’s important to understand and keep track of these config vars on a production Heroku app. While a development mode is typically great for development, it’s not so great for production - leading to a degradation of performance.