PHP Web Deployment Using Git
I've recently been working on a new version of my personal website, which can be found over at http://www.alastairsmith.me.uk/. I wanted a light-weight site that would pull in data from my various presences across the web including my two blogs, GitHub, and Google Picasa; furthermore, as much as possible should be hosted on some form of Content-Distribution Network (CDN). Google's CDN is serving up jQuery and jQuery UI quite nicely for me whilst minimising the amount of stuff I need to administer and maintain myself.
It's generally a good idea when developing web applications to keep your in-development version separate from your production version; indeed this goes for many development scenarios, including in-house application testing before rolling out to users, desktop software development, and others. The backbone of such a strategy is a good source control system, and whilst centralised source control like Subversion can handle this capably, a certain amount of friction is involved in setting it up. Distributed version control systems, and Git in particular, can remove this friction.
Because my personal website is so small by design, the friction of setting up a centralised source control system for deployment scenarios for such a tiny application would have been great enough to put me off looking into it any further. Luckily, I switched to Git as my version control tool of choice about a year ago, and haven't really looked back. Here's how I accomplished a simple web deployment mechanism that can work for sites with a back-end component as well as a smart front-end.
After a bit of Googling, I came across this Stack Overflow answer which accomplishes everything I need in a very simple and frictionless manner. It requires minimal set-up, and, once complete, deployment is as simple as running
git push production. How neat is that?
In essence, the solution is to check out your web application from your Git repository to your production web server, create a post-update hook that will update the web server's working copy after a push operation, and create a new remote configuration entry in your development copy. You can then hack away in your dev copy, run all the necessary tests, and push it up to the production server when you're satisfied with it. The post-update hook is the trickiest bit of the process, and even that has been completed for you and is available from the Git wiki.
There is a further step alluded to in the comments on that answer, which is to ensure you lock down your .git directory on your production web server. Exposing that directory and its contents can provide the entire source code for your application, which is likely not what you want, particularly from a security perspective. I'd forgotten most of my Apache-configuration-fu so it took me a while to work out the correct .htaccess directives, but it would appear to be relatively simple: create an .htaccess file in your .git directory and enter the following code:
deny from all
You will also likely want to add the following code to an .htaccess in your application's root directory (i.e., the parent of the .git directory):
Similar access controls will need to be set in other web servers such as IIS; non-Apache configuration is left as an exercise for the reader.
The only down-side to this solution (which, realistically, is unavoidable) is that the new remote configuration needs to be specified on each working-copy you wish to develop in, but that is a quick and easy thing to define. It may also cause you to forget to push to your origin repository regularly, as you push to production instead, but this isn't anything a little discipline can't solve.