Hacker News new | ask | show | jobs
by Codayus 5315 days ago
Point 3 - Config: The claim is that you shouldn't have a config file that you don't check into source control like Rails' config/database.yaml, or the common Django settings_local.py. Instead you should use environment variables. Um. I see the point,but I also see two problems with this.

1) I'm certainly not going to set env variables with database passwords and such by hand. I'm going to have a script to do it for me. I might even call it, oh, I dunno, settings_local.py. In which case, I'm right back at square one, needing to not check this into source control. In other words, how do you avoid having the database passwords in SOME file, SOMEWHERE? Does it "fix" anything if it's named "fabfile.py" instead of "settings_local.py"? I can't see how.

2) How do I deploy multiple apps to the same server? Let's say I've got a linode (or EC2 instance, or whatever) running a test, dev, and production deployment of three different apps. With config files, I just have a different settings_local.py file in each deployments project directory. With environment variables...what, do I use prefixes? app1_test_dbpass = 'foo'; app2_prod_dbpass = 'bar', and so on? Except they say NOT to group stuff together into environments by name. So uh...how do you manage name collisions?

Basically, they seem to have identified a real problem, then proposed a solution that doesn't fix it and doesn't work. What am I missing?

5 comments

I recently switched from various settings.yml files to a bash script. I can't believe I hadn't made the move sooner! Such a huuuge improvement.

A few good reasons:

1) Language agnostic -- I can use common configuration for Ruby, Node.js, Makefiles, Bash scripts, etc. Without having to find/use a parser for my config file settings, nor worrying about executing a Ruby script from a Python process, or whatever.

2) Real programming constructs -- I can easily test a boolean condition, interpolate variables, and otherwise minimize copy/paste between configuration sections.

3) Available at bootstrap -- Don't need to install Ruby or Python or anything like that. The very first scripts I run can use the environment without compromise. Particularly useful because machines are bootstrapped with Makefiles, which play well with the environment.

I modeled my app env script on the behavior of the `env` command (in fact, I delegate to it). See an example script in this gist:

https://gist.github.com/1388478

Note the examples. By delegating to `env`, you get a few features for free:

1) Executing any process within the environment

2) Passing additional environment variables on the command line

3) Printing of environments (great for diffing!)

My preferred approach to this is:

1. Have a script that defines environment variables your app uses, and name that script ~/.bashrc, user accounts are cheap and provide an excellent way to have isolated environments.

2. Check an example copy into the project itself. The application does not source this script itself. This documents the dependencies of the app.

Disclaimer: I've never deployed on anything that wasn't unix-like.

I use chef and runit's chpst (like envdir) to set the environment variables.

The production / staging environment chef configuration is stored in a tightly-locked down git repository that can only be accessed from production.

Chef reads the production configuration information, puts the environment variables into envdir-complaint files in a directory, runit uses chpst/envdir to start the process with the correct environment settings... and that's pretty much it.

The main thing is your configs lives somewhere different than the code. They can both be source control somewhere. Though I generally keep a localhost config with my code.

Just define an env variable or something that contains the location of settings.py, a directory thats managed by something like chef/puppet.

Yeah, that part didn't make much sense to me. Say I have 5 different projects, which when developing may need 5 different sets of environment settings on my local computer.

So obviously I need something that contains and applies these settings. What makes this any less likely for me to accidentally commit that than the files they're objecting to?