(Hero)ku (Conf)iguration makes handling config and secret parameters between local environments and heroku easier.
Installation through NPM:
npm install -g heroconf
This is how your code should look. It's pretty simple. Just require heroconf, and then use heroconf to require your local configuration file. Now you can use the get
method of the configuration instance to seemlessly access your variables.
var heroconf = require('heroconf');
config = heroconf.require(__dirname + '/my-local-config.json');
config.get('secretKey'); // returns secretKey
Sometimes you have a range of difference configurations and therefore would like to prefix them in heroku with a few letters. Instead of having secret
, you will maybe like to have aws_secret
and firebase_secret
respectively. If this is the case, then you can add a second parameter to the require
function and all variables will be prefixed:
var heroconf = require('heroconf');
firebase = heroconf.require(__dirname + '/firebase.json', 'firebase');
firebase.get('secret'); // returns firebase_secret variable
It's important to notice, that every Heroku command is executed from your current working directory. So navigate to the folder which contains your Heroku project, and then start using HeroConf!
Imagine you have a local configuration files like this:
// file: firebase.config.json
{
"secret": "SOSECRETWOW"
// ... 15 other secrets or just configuration variables
}
Then you can push all these configurations variables to Heroku with one command:
$ heroconf push ./path/to/my/firebase.config.json
Output:
Setting config vars and restarting bonzaidev... done, v266
secret: SOSECRETWOW
Again, sometimes you want to prefix your variables in heroku. This can be done by adding an extra parameter to the command:
$ heroconf push ./path/to/my/firebase.config.json firebase
The varibles will now be prefixed with 'firebase', and you will need to add this prefix in your code when calling the require
method, to properly access the correct variables.
Setting config vars and restarting bonzaidev... done, v267
firebase_secret: SOSECRETWOW
Maybe you are more than one person on a team, maybe you like to wipe your hdd. Anyway, you can retrieve the remote Heroku configuration and put it into a file by executing this commmand:
$ heroconf pull ./path/to/new/file/heroku.config.json
Now, every configuration variable from Heroku will be fetched and put into the file and can now be edited, pushed, and used in your code. Awesome!
As said, sometimes you've prefixed your variables in Heroku and maybe want to keep them in separate files, you can achieve this by adding a second paramter to the command:
$ heroconf pull ./path/to/new/file/aws.config.json aws
$ heroconf pull ./path/to/new/file/firebase.config.json firebase
Now every variable in Heroku starting with 'aws' will go into the aws.config.json
file, and all variables starting with 'firebase' will go into the firebase.config.json
file.
Notice that the pull
operation is non-destructive. Meaning that it does not override existing variables if the file you are pointing to already exists.
If you want to remove the remote configuration created by a local file, you can do so. The following commands will unset the variables in Heroku.
$ heroconf clean ./path/to/local/config.json
Unsetting secret and restarting bonzaidev... done, v268
If working with prefixes, we follow the usual syntax:
heroconf clean ./path/to/local/config.json prefix
Unsetting prefix_secret and restarting bonzaidev... done, v269
Sometime humans mess up stuff. I do at least. Then it's nice to just wipe your heroku configuration, and start clean. You can do this by simply executing:
heroconf destroy
BOOM. The Heroku configuration refered to from your current working directory will be unset!
heroconf push ./path/to/file.json [optional prefix]
heroconf pull ./path/to/file.json [optional prefix]
heroconf clean ./path/to/file.json [optional prefix]
heroconf destroy
Your local configuration file should look something like this (notice that heroconf do not support nested configuration files yet!):
{
"secret": "booyaah",
"authKey": "authauthauthkeykeykey"
}
When you develop locally and deploy via git to heroku, you will often do something like this to preserve your applications secret values:
- Have one or more local .json configuration file with the secret values
- Add this .json configuration file to your .gitignore file, so it won't be exposed
- Instead of using a config file when deploying to heroku, you will use heroku's environment variables
For you application to handle those two differences, you must do something like this in your code, which is cumbersome:
var config = {};
try {
config = require(__dirname + '/config.json');
} catch (e) {
// doesnt matter
}
// using the config value:
console.log(process.env.MY_SECRET || config.secret);
The simple solution is heroconf, which will handle the above for you much more elegant as seen in our examples above. Internally something very similar to what we did above actually happens.
We want to implement the following features:
- Add support for recursive dot-notation (
conf.get('my.nested.secret')
) - [DONE] (Thanks to mickhansen for providing solution!) Provide solution not dependent on CoffeeScript (we don't like unnecessary dependencies!)
- [DONE] Feature heroku synchronization, so you don't have to maintain your variables manually at heroku
If you have any comments, feel free to dorp me a message at henrik [at] bonzaidev [dot] com.