gitdeploymentdevelopment-environmentconfiguration-filesweb-deployment-project

Git: application configuration and different environments


We use git for most of the web applications we build in our shop, and though the applications themselves use a variety of technologies (PHP, Rails, etc), we generally have a staging and production server for each site. Typically, these servers have different sets of database credentials as well as different environment-based configuration settings (e.g. caching). Our workflow generally involves maintaining two git branches per project: master, which reflects the production server, and staging, which reflects staging. New features are developed on staging (or a sub-branch) and are merged back to master upon completion and deployment.

My question is with respect to the best way to maintain the configuration files that are branch- and environment-specific. I've seen the answers from similar questions here and here, and neither really satisfies. The main two approaches seem to be a) using .gitignore exclusion to leave config files outside of git's purview, or b) writing reflective, environment-aware code that determines e.g. what database credentials to use based on hostname. My problem with a) is that it only allows one set of config files to exist in the codebase (irrespective of the current branch), so the other environment's config files get lost. b), on the other hand, just seems to require unnecessary modification of the codebase in a way that doesn't feel related to the application's functionality.

Ideally, I'd like a way to "lock" configuration files within a certain branch, so that whenever I checkout master, I get the master config files, and whenever I checkout staging, I get the staging config files. Additionally, merging staging into master shouldn't affect the master config files in any way. To date, we've dealt with this by having folders containing environment-specific configuration files outside of the git root and manually moving the appropriate files into codebase when deploying, but this is of course needlessly hackish (and potentially dangerous).

Is there any way to accomplish this using git?

Thanks for your consideration!


Solution

  • Not sure why people think they can get away without some sort of install tool. Git is about tracking source, not about deploying. You should still have a "make install"-type tool to go from your git repo to the actual deploy, and this tool might do various things like template expansion, or selection of alternate files.

    For example, you might have "config.staging" and "config.production" checked in to git, and when you deploy to staging, the install tool selects "config.staging" to copy to "config". Or you might have a single "config.template" file, which will be templated to make "config" in the deploy.