As this is powered by jekyll/octopress, it's worthwhile to go into some detail about how to serve it on a Linode (or equivalent) and how to autoregenerate the whole site with a simple git push.

The plan

  • Use git for blog content version control/backup
  • Remote repository on the deployment server
  • When I git push to the deployment server, automagically (re)generate the static pages
  • Serve with nginx

Server prerequisites/assumptions

Client prerequisites

Server Setup

make a bare git repo

mkdir -p repos/blog.git
mkdir -p tmp/blog
cd repos/blog.git
git init --bare

make a destination for the static files

sudo mkdir -p /srv/www/example.com/static
sudo chgrp www-data -R /srv/www/example.com/static
sudo chown user -R /srv/www/example.com/static

The way we are going to trigger the static site generation is via
git's hooks, specifically the post-receive hook. We can write a simple script like this

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/env bash

export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"

GIT_REPO=$HOME/repos/blog.git
TMP_GIT_CLONE=$HOME/tmp/blog
PUBLIC_WWW=/srv/www/example.com/static
JEKYLL_SRC=$TMP_GIT_CLONE/source

git clone $GIT_REPO $TMP_GIT_CLONE
cd $TMP_GIT_CLONE
bundle install
rbenv rehash
compass compile --css-dir $TMP_GIT_CLONE/source/stylesheets
cd $TMP_GIT_CLONE

jekyll build
cp -rf $TMP_GIT_CLONE/build/* $PUBLIC_WWW
rm -Rf $TMP_GIT_CLONE
exit

And save it to the server as $HOME/repos/blog.git/hooks/post-receive. It is also important to make it executable chmod +x $HOME/repos/blog.git/hooks/post-receive

It took me a while to get the script to run properly. Initially I used RVM for the server ruby installation. I ran into some problems with it and finally opted to use rbenv instead. Curious? Check this.

Nginx needs to be setup to serve a static site.
A configuration like the following can go to a file /etc/nginx/sites-enabled/blog

server {
    location / {
        root /srv/www/example.com/static;
    }
}

And then we can

sudo service nginx reload

Local Setup

clone octopress

git clone git://github.com/imathis/octopress.git blog

set remote to be our git server

cd blog
git remote rename origin octopress
git remote add origin ssh://user@someexample.com/home/user/repos/blog.git

create blog and first post

bundle install
rake install
rake new_post["a title goes here"]

Done editing? Add, commit and deploy with a simple push

git add .
git commit -m 'First blog post'
git push -u origin master

If all went well, you should see the output of the post-receive hook on your command line.
Sample output might look like this

remote: Cloning into '/home/user/tmp/blog'...
remote: done.
remote: Using rake 0.9.2.2
remote: Using RedCloth 4.2.9
remote: Using chunky_png 1.2.5
remote: Using fast-stemmer 1.0.1
remote: Using classifier 1.3.3
remote: Using fssm 0.2.9
remote: Using sass 3.2.9
remote: Using compass 0.12.2
remote: Using directory_watcher 1.4.1
remote: Using haml 3.1.7
remote: Using kramdown 0.13.8
remote: Using liquid 2.3.0
remote: Using syntax 1.0.0
remote: Using maruku 0.6.1
remote: Using posix-spawn 0.3.6
remote: Using yajl-ruby 1.1.0
remote: Using pygments.rb 0.3.4
remote: Using jekyll 0.12.0
remote: Using rack 1.5.2
remote: Using rack-protection 1.5.0
remote: Using rb-fsevent 0.9.1
remote: Using rdiscount 2.0.7.3
remote: Using rubypants 0.2.0
remote: Using sass-globbing 1.0.0
remote: Using tilt 1.3.7
remote: Using sinatra 1.4.2
remote: Using stringex 1.4.0
remote: Using bundler 1.6.2
remote: Your bundle is complete!
remote: Use `bundle show [gemname]` to see where a bundled gem is installed.
remote: unchanged sass/default.scss
remote: unchanged sass/syntax.scss
remote:    create source/stylesheets/screen.css
remote: unchanged sass/main.scss
remote: Configuration from /home/user/tmp/blog/_config.yml
remote: Building site: source -> build
remote: Successfully generated site: source -> build

Furhtermore, your blog should be live!