Posts
Environments, Deployment, Subversion, Hoorah!

The MVC framework of choice for me is Symfony. It’s extensible, malleable, full-featured, and straightforward. Once you get through the online book, it’s smooth sailing for any standard web application, AJAX or not. For tiny projects I might opt out for my own lightweight retarded MVC implementation, but otherwise Symfony works great for the projects that fit will into the MVC pattern. And yes, there are plenty of applications for which MVC is a shit idea.

I’ve started running in to a few issues that I kept pushing to the back burner; environment configurations, deployment, and Symfony release versions. Though I’m talking about Symfony specifically, what I’ve to say could apply to virtually any code dependencies.

I’ve decided to simply everything and use Subversion to deal with all of it. Years back I wrote a rather complicated PHP deployment system for deploying source-controlled applications from various locactions to various servers. This was nice, and it let me give developers in my team access to deploy to servers they didn’t even have an account on, but it was bulky and complicated. Hence, my new solution.

Step 1. Make sure all your code is in Subversion. Always. For web applications, be sure the ‘web root’ folder is not the root of the project, and remember to, at the least, use a proper project/trunk, project/branches and project/tags structure.

Step 2. Roll all dependencies into the Subversion structure. Symfony documents this on their installation guide, in fact (as one of the options). Essentially, you’re going to connect your project to all its dependencies using the handy not-so-often-used svn:externals property. In the case of Symfony, I simply set the svn:externals property of the trunk/lib/vendor to be “symfony http://svn.symfony-project.com/branches/1.X”. All it does is says the directory trunk/lib/vendor/symfony is tied to an external SVN source. Next time I svn update or svn co, it magically imports the Symfony release and the dependency is satisfied.

This has the wonderful property (and I hate aspects of Java for often forgetting to address this) of removing the long “configuring your environment” step. Yes, it can be quite wasteful if you have a number of projects that all use the same version of Symfony… but who honestly cares about the extra few meg of disk consumption for the versatility it gives you?! A single project decides to change to a different version of Symfony, or change entirely to CakePHP. No big deal. Alter the dependencies, and you’re all set - on every environment! Development, testing, QA, production, whatever! Woohoo.

Step 3. Environment configuration is the second headache. So, we use the tools we already have to keep things simple. Create a directory in the root of your project called env (e.g. project/trunk/env). I keep it within the project itself, but if you want greater user-access-control, you might consider keeping it in a seperate SVN project entirely. Within this env, you’re going to create a series of directories, each of which represents a single environment the application can run on. I usually start with my own development system We’ll call it, say, “tysondev“. So, I create trunk/env/tysondev. Inside of here all I do is recreate the appropriate Symfony (or whatever) directory structure, and scatter about it all of the files that might need to be changed based on the environment the application is being deployed. For Symfony, here’s what I’ve come up with:

  • /env/tysondev/apps/APPNAME/config/app.yml
  • /env/tysondev/config/databases.yml
  • /env/tysondev/config/propel.ini
  • /env/tysondev/config/ProjectConfiguration.class.php (symf1.1)
  • /env/tysondev/data/fixtures/*
  • /env/tysondev/web/*.php  <– all front end controllers

Simple. I then configure each file appropriately for my development environment.

Step 4. Now, we need to make sure Subversion doesn’t mix up configurations and overwrite something. We delete every file that we just put in the tysondev/ out of the trunk. E.g. delete (svn del) trunk/config/propel.ini. For all of them. Once they’re deleted, you can even add them all to svn:ignore if you want to be really sure things won’t get messed up. This ensures that the configuration will always come from the appropriate env folder- the active configuration won’t be in SVN. Also - to create new configurations, just svn copy an existing one. It’s more efficient that way :)

Step 5. Merge whatever configuration you want. You simply want to copy the env/tysondev folder into the root, without bringing with it any of the .svn files. I wrote a tiny PHP shell script to do just this, though you could easily do it in a single shell command using find. Whichever you’d like.

Step 6. Enjoy. You now can easily separte configurations from the rest of the code, manage dependencies in a system-independent manner, deploy to a machine using two commands: svn co or svn export, and then php mergeconfig.php tysondev. That’s it! Of course, dealing with your database is going to be an additional headache, and there are plenty of ways to to do it. Symfony handles a few simple ways. I leave that for you to decide, since having a cookie-cutter script manipulating your production tables is scary.

-t

Leave a Reply

2 Responses to “Environments, Deployment, Subversion, Hoorah!”
rpsblog.com » A week of symfony #97 (3-&gt;9 november 2008)
09 Nov 2008
6:54 pm

[...] Environments, Deployment, Subversion, Hoorah! [...]

fred
11 Nov 2008
1:31 am

did you try fredistrano ?
http://code.google.com/p/fredistrano/
this tool allow to deploy any web application from subversion