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):

Options -Indexes

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.

Comments

90% of my application lives beneath the public web tree, e.g.:
/var/www/app/source/
/var/www/app/public_html/

Everything is stored in GIT though: the .git folder would be in /var/www/app/ but that's not accessible through web.
What would be the solution? I don't want all the code 'above' the webtree (publicly accessible). Any ideas?

Hi Rudie

I'm not sure I follow what you're asking. Your folder "app" contains your application, which has two subfolders, source and public_html, as well as the .git repository metadata directory. Is your app folder publicly accessible, or is it only everything from public_html down that is publicly accessible?

You can use .htaccess files to control access to the different folders in your application in as granular a fashion as you need. For example, you could use the same .htaccess file I described in the post inside your "source" folder if you want to hide this. You can also configure Apache to point your domain at the public_html folder itself, hiding sibling and parent folders from the web. Check out the Apache docs for your version for more information.

Alastair

-- Alastair

Hello !

apache default has :

Order allow,deny
Deny from all

That says prevent access to all file swith a filename that starts with .ht (hence the .htaccess or .htpasswd).

You can do the same for git once and for all :

Order allow,deny
Deny from all


or .svn etc...

Thanks, I think that's a more elegant solution to the problem :-)

-- Alastair

Add new comment