Samlr.com 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.
#!/bin/bash
GIT_WORK_TREE=/var/www git checkout -f
echo "changes pushed live"
EOM
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 git@yourserver.com:~/some_dir.git
# 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...
Troubleshooting
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).