Comment by zzzeek

15 years ago

"The twelve-factor app stores config in environment variables (often shortened to env vars or env). Env vars are easy to change between deploys without changing any code; unlike config files, there is little chance of them being checked into the code repo accidentally"

OK guess I'm a moron here but....surely the suggestion isn't that a huge set of env vars are entered at the console manually - they have to be in some shell script or file which produces them...which is then...the config file ! Someone help me see what I'm missing here.

Unless the idea is, "well it's a shell script! that's nothing like a config file!" in which case I'll be searching for the HN downmod button I can't wait to have someday.

`envdir` [1] is a common pattern for maintaining environment with a directory of key/value files.

If you use `foreman` [2] to manage application process formations, it will source a '.env' file before running.

You could call either pattern a "config file" but the important part is that its actual Unix environment variables, and there is a safe and secure place to store the variables outside of the code repository.

Then... you can take a huge leap forward when running on Heroku. Heroku has an API to set environment variables:

  $ heroku config:add API_PASSWORD=abc123

That value will be present in the runtime environment for the life of your application. So you do enter them manually -- but only one time when setting up an app.

The really clever part is that 3rd party add-on providers can also set environment variables on your app with a similar API. So if your database is an add-on:

  $ heroku addons:add redistogo
  $ heroku config
  REDISTOGO_URL => redis://user:pass@host-1:9492/
  
  $ heroku addons:upgrade redistogo:medium
  $ heroku config
  REDISTOGO_URL => redis://user:pass@host-2:9133/

If settings are in config files, you would have to deploy new code to change settings, and you wouldn't have a way for your hosting platform to help manage settings.

[1] http://cr.yp.to/daemontools/envdir.html

[2] http://ddollar.github.com/foreman/

In a well run environment there are generally special tools that can provision a new node, generally these kind of environmental configurations are set up there. Some people do manage it in source control and just have a branch for each environment. Both work, but one provides an avenue to offload the task from a developer onto an infrastructure type role.

  • The choice of a config file and/or environment variables seems more sensible.

    • I personally am not a fan of config files at all, a lot of this stuff comes down to preferences and experiences, but I have seen the environmental configurations being put in config files problem repeated over and over, then someone checks in the config with the project and someone checks it out and then it gets installed in an environment. It is considered good practice to separate configuration data from the code entirely, so that a commit, with config files, to source code cannot blow up an environment. Many recommend, as is the case with this author, that that separation happen by putting the config in environmental variables, that way it is wholly separated from the application and an updated to the application cannot blow up an environment. I agree with the conclusion and through experience, have found it to be the best solution as well. That beings said, using a tool like Puppet to automate and turn over, the process to infrastructure, is pretty simple, but some groups don't like to use tooling and if not, having an environmental configurations script in a separate repository, is just as valid of a process and will reduce the failure point.

      5 replies →

yeah, I'm not a fan of using environment variables. Using symlinks has always seemed more stable to me.