You Asked For It: Chris' Awesome But Short Guide To Deployment Using Phing

I have been suffering from a major case of blogger's block, so I reached out to the lucky people who follow me on Twitter to ask them about some topics to talk about on the blog. Thanks to them I've got at least two blog posts coming. Credit to this one goes to Neil Crookes (who I met at the first CakeFest conference in Orlando) who suggested I talk about deployment issues

What's that you are saying? You thought I was using Capistrano to do deployments at work? Gentle reader, things change. All my work in trying to automate deployments is designed to allow me to do a deployment either from my own laptop or remotely on the server where it's run. Tools like Capistrano and Phing let me do that. Sure, I could cobble together my own solution using rsync or shell scripts, but my experience telecommuting has taught me that if you want others to use your tools, they have to be tools that can be used by others.

While Capistrano is certainly up to the task of deploying my own personal projects, I had nothing but problems getting people OTHER than myself to get it up and running. You wouldn't think that getting Ruby and then assorted gems installed on a non-Windows machine would be that hard. Apparently it is. So what was my alternate solution? Create something that can be run on the server where the code is going to be deployed.

As a guy who is always up to his neck in the devops environment (with a tip of the hat to Brian Moon for bringing this term to my attention) I am determined to NOT be the only one who can do deployments. It's 2010, the year we make contact, and there is no reason that my boss, when he alters some marketing copy on our main web site, should not be able to push those changes himself (with the side-effect being leaving me out of it). With a little work and some digging, I got Phing to do it for me.

Like many awesome tools with lots of documentation, Phing suffers from a lack of easy-to-find tutorials covering the exact things I wanted to do. Or sure, I eventually tracked it all down (with the help of the best support group in the world, Twitter) but I'm guessing this a trend that will not go away.

So, being the lazy sort, I set out to duplicate how Capistrano does their deploys:

  1. Check out the latest version of code from HEAD on your repo (SVN in this case)
  2. Create a new "current" directory
  3. Symlink the latest checkout (which is in release/yyyymmddhhmmss) to current
There are some other steps in here that I use as well that are specific to my applications but these are the basics.

Why the symlink method? Capistrano allows you to also rollback to a previous deployment, but I haven't gotten around to implementing that feature with the new Phing-based setup. I never make mistakes that need to be rolled back like that. Yes, I'm kidding.

So, what would a build script to cover the basics look like? ~~~ < ?xml version="1.0"?> ~~~ I know there are XML haters out there, but that's a readable configuration file right there. One of the things I did was to remove any user name and password information from the config file. You never know if you'll get cracked by a script kiddie exploit and someone reads a configuration file full of critical information. Call me paranoid, butyaneverknow.

So, after you install Phing then to run things you just need to type 'phing -f '. In our case, I then get prompted for a password, as the user names on the servers are the same as for the SVN repo.

So what else do I do when I deploy? There is always some clean-up work to be done after the fact, so I add a few more actions to the file: ~~~ ~~~ I won't get into the details of what I'm doing there, but you can execute any command you want on the server, so long you have permissions to do so.

So, sometimes you are lazy and don't want to mess around with symlinks and figuring out how to roll things backwards. Here's how you could do a deployment using Phing that simply updates a directory that you checked out using SVN already: ~~~ < ?xml version="1.0"?> ~~~ Again, very straight-forward. Phing is a very powerful tool that can be used for a lot more than just deployments. Browsing through the documentation gave me some ideas for extending Phing further to meet our deployment needs. If you deal with PHP all the time, I cannot think of a better tool to help with complex build-and-deploy tasks than Phing.