the making of

Posted: 27th May 2013

tl;dr: quick how-to, devised by Abhijit Menon-Sen's, any mistakes are my own. I've added a couple of troubleshooting points that I encountered and I have some waffle below about why I did things this way.

Waffle (or preface, you choose)

At long last this site is live. As you can see from the dates on the other blog posts I started work on this 3 months ago and I've been working pretty inconsistently since then, actually that's a lie: checking github I started work back in January but the early posts were lorem ipsum so we don't talk about those.

So, this post is an attempt to document how this site actually runs, I've already discussed the lovely little script that produces this site but now I'm going to talk a little about how the site itself is run. The idea is simple: I have a static site, the static site is mainly text, git is excellent at spotting changes in text and moving them about, let's use git to sync the site. This has all sorts of benefits: firstly the site is kept nicely backed up, secondly the generated/dev site is kept decoupled from the production[1] site and finally it means that all publishing is done via a simple git push web command when I'm ready.

The basis for this system is Abhijit Menon-Sen's guide and the idea is very simple. You create a git repository on the hosting server, use the post-receive hook to then checkout those changes in a different directory (e.g. /var/www or where ever you have your server keep stuff). The hook is a script which is called when ever the server receives changes. The script Abhijit's guide suggests then forces a checkout into the GIT_WORK_TREE[2] which pushes everything live.


That was the idea anyway... and then I spotted that Tachikoma (reasonably) nukes its output directory every time its run which takes with it the git repo I had in there. The solution to this? Two repos (and a publish script). At this point I could have done the simple thing and just set up FTP. Except I've tried this, it's never gone well, and ultimately having git still means that the site is more well backed up and much easier to roll back, also I like git.

How to

Create a new git repo on your host server

mkdir some_dir.git    # '.git' is optional but convention
git init --bare       # 'bare' because the work dir will be elsewhere
cd some_dir.git/hooks

Now create the hook script that will deploy our site where we want it (obviously substituting where ever you want it for '/var/www')

cat > post-receive << EOM  # or vim etc.
GIT_WORK_TREE=/var/www git checkout -f
echo "changes pushed live"
chmod +x post-receive        # Make sure git can run the script

Back on your local server you want to init you repo, create & commit something

mkdir local_some_dir
git init
echo "It's alive!">>test.html 
git add test.html
git commit -m "Hot damn, it works!"

Let your local repo know where to push and then push!

git remote add web 
# where 'git' is whichever user has the repo
git push remote master

Now if everything's gone according to plan you should be able to access test.html from your server, if not: here are a few problems I encountered and what I think are the fixes...


Variants on incorrect permissions

I saw this, a lot, mainly because I ran a few variants on the set up but remember this: your git user needs access to both /var/www and the repo itself, if you've set up your git repo using the git book then you've likely got a dedicated git user, who has the nologin set, this means that another user has to make the git repo (and the post-receive hook), if these aren't chown-ed to git it won't be able to access them. The same with /var/www, it's unlikely that your git user will have write permissions to your live web directory so you might need to change these (I added git to group www-data)

No test.html on the server

I'm not certain why this happens but I found that sometimes the hook only properly deployed on a second push; sorry but try turning it off and on again. Obviously if this doesn't work check your logs etc. The output from the push should be everything that the post-receive script produces (so you should see changes pushed live get echoed back).

[1] as if this is anywhere near that professional. back

[2] git allows you to split a repo into a work tree and a git dir, this variable just tells git that the work should be checked out else where. back