dev vs. live

ChrisDolan on 2007-06-04T05:25:50

In any web app, it seems that there's always something that you want to be different on the live site versus the dev site: a different database name, verbose logging on, performance metrics enabled, etc. I find myself implementing the live vs. dev switch a little differently every time, though. What do other people do? Do you trigger dev behavior via hostname? Via a config file? Via an URL substring? Manually?

In my current Catalyst project, I wrote this little hack. It's inelegant, but simple to understand.

# If we aren't running on my development computer, refuse to load the dev features                                    
if (! -d '/Users/chris') {
   # trick Perl into thinking this file is already loaded                                                            
   $INC{'MyApp/Controller/Dev.pm'} = 1;
}


where Dev.pm adds a few special features and flags. This works because my main dev box is a Mac and the servers are all Linux or FreeBSD, which use /home instead of /Users.


Via a configuration class

Alias on 2007-06-04T06:54:58

I'm increasing going config-driven.

I centralize all the platform-specific stuff into a .ini or YAML-style config file.

Then there's a config class which has the task of loading it and thoroughly checking everything in it (file permissions, paths existing, initializing the database connection pool etc). It takes a fail-early approach, and then various configuration values and objects are provided via the static methods for the config class.

All the rest of the application looks to this class for information, so a typical launch script might look like...

#!/usr/bin/perl

use MyApp::Config ROOT => '/home/production/myapp';
use MyApp;

MyApp->run;


The nice thing about this sort of setup is that if you do it right all the tests will just run against whatever version of MyApp is loaded...

Then in the repository I have myapp.conf, myapp.conf.stage myapp.conf.production etc...

The deploy script exports from the repository, overwrites myapp.conf.production over the myapp.conf, and then runs the tests, etc etc...

The operator can check and modify the production configuration by hand if needed, without having to touch code.

Or I do some variation on this general theme...

But I've always had trouble putting configuration into the application, the longer I work on web apps, the more important I think it is to have all the platform-specific stuff in a configuration.

I use the Apache conf

grantm on 2007-06-04T21:47:20

If I'm deploying on mod_perl, I tend to set this sort of thing up using PerlSetVar in the Apache config rather than create an application-specific config file.

That Way Lies Madness

jaw6 on 2007-06-05T00:30:28

I've done things like that in the past (or sniffing version numbers of various programs/libraries, and guessing environment therefrom), but I suspect that way lies madness, ultimately -- at least, pick one thing and stick with it, or you will inevitably forget what the decider is for any given app.

I tend to prefer the config file method -- it also allows a slightly wider matrix (development vs. production is common, but many leave off staging, or laptop, or home machine). Ideally, there would be two axes: "configuration" (passwords, databases, etc.) and "mode" (development vs. production, etc.)

dev vs live

echo on 2007-06-05T15:11:27

I use a second config file where I put site specific values. The application loads both config files, values in the second one override those in the first config file. This way no ugly code hacks like the one you posted.

okay for dev+prod

slanning on 2007-06-05T15:40:25

If you have a "dev -> stage -> prod" setup, where stage is ideally as close as possible to prod, then what you have won't work. You need a more general way to get the configuration, like a config layer that parts of the application can call through (database, etc. goes through this layer).

Dealing with different configurations sucks, blech. Like when you want to sync your dev from prod, you always end up changing something: a server name in a database table, in a config file, etc. I guess ideally you need a way to automate the application of a configuration to each machine. So if you do like a raid disk copy to sync your dev machine from prod, then you have a script that has some parameter, like "./apply-config --to-server=dev.example.com --type=dev" or "./apply-config --to-server=prod.example.com --type=prod", where the script knows that "prod" means a certain configuration but "dev" means another config.

Well, I guess that has less to do with programming than sysadminning, though.