My setup for blogging with Nikola

2013-02-27 23:51

This blog is powered by Nikola - a great, lightweight python static page generator. In this post I wanted to share the setup I use for easily and effectively blogging with it.

First, I got Nikola installed on both my local machine and my server. This might sound unusual at first since the whole point of a static page generator is that you deploy by sending just the rendered pages to your server. However, here are my considerations:

  • why would I always send all those html, css, js and possibly image files (if they change)
  • what happens if I lose my laptop for any reason

Taking that into account I came up with another solution. I don't use Nikola's built-in deploy config option. Instead, I track my posts (actually whole site) in mercurial. Then I use its hooks to actually command Nikola on my server to build it with new content and put the results in the public-facing dir.

This way I have to send only the new posts or any typo fixes over. Additionally I can keep track of my posts in mercurial, but I am not yet sure what use I will have for that.

First, setup Nikola on your server. I do it in a virtualenv inside my homedir and I use latest git version (by the way, that's one of the perks of static page generators. You can use the bleeding-edge version and still be alright. If it breaks, just fall back to an older version and regenerate your site before deploying):

~ $ virtualenv --no-site-packages nikola-virtenv
~ $ cd nikola-virtenv/
~/nikola-virtenv $ source bin/activate
(nikola-virtenv)~/nikola-virtenv $ git clone https://github.com/ralsina/nikola.git
(nikola-virtenv)~/nikola-virtenv $ cd nikola/
(nikola-virtenv)~/nikola-virtenv/nikola $ pip install -r requirements.txt
(nikola-virtenv)~/nikola-virtenv/nikola $ python setup.py install
(nikola-virtenv)~/nikola-virtenv/nikola $ ..
(nikola-virtenv)~/nikola-virtenv $ nikola init testsite
Created empty site at testsite.
(nikola-virtenv)~/nikola-virtenv $ cd testsite/
(nikola-virtenv)~/nikola-virtenv/testsite $ hg init

Here is the cool part. We setup 2 hooks in mercurial:

  • changegroup - will run when we push to the repo, and it will update the repo with the new stuff
  • update - will execute our build script

Put this in your .hg/hgrc:

[hooks]
changegroup = hg update >&2
update = ./build_site.sh

The build_site.sh script is really simple. It just enters the virtualenv, instructs Nikola to build and then actually deploys the resulting files to the webserver dir if everything went alright.

#!/bin/bash
. ../bin/activate
nikola build
rc=$?
if [[ "$rc" != 0 ]] ; then
        echo "Errors building site"
else
        echo "Site built OK, deploying"
        cp -r output/* /<www_dir>/
fi

Remember to make it executable by chmod +x build_site.sh.

On my local machine I setup Nikola in a similar fashion (virtualenv, etc. Just remember to match your python versions!), then initialized mercurial repository like so:

... install Nikola like above ...
(nikola-virtenv)~/nikola-virtenv $ nikola init testsite
Created empty site at testsite.
(nikola-virtenv)~/nikola-virtenv $ cd testsite
...set everything up (theme, conf.py)...
...create .hgignore file (below)...
(nikola-virtenv)~/nikola-virtenv/testsite $ hg init
(nikola-virtenv)~/nikola-virtenv/testsite $ hg add

Put this in your .hgignore file:

syntax: glob
.*
output/*
cache/*
*.pyc
__pycache__

It's important to add output/* (among others) to .hgignore file so that when you build locally it doesn't pollute your repo.

In .hg/hgrc put your server config (I assume you have your ssh keys setup):

[paths]
default = ssh://admin@server/~/nikola-virtenv/testsite

Finally here is the complete workflow (on your local machine):

... enter virtualenv and your blog`s dir ...

$ nikola new_post
Creating New Post
-----------------

Enter title: My setup for blogging with Nikola
Your post`s text is at:  posts/my-setup-for-blogging-with-nikola.txt

... write your post ...

$ nikola serve
Serving HTTP on 127.0.0.1 port 8000 ...

... check your new post in a browser ...

$ hg add posts/
$ hg ci -m "New Post: My setup for blogging with Nikola"
$ hg push

... now you should see the usual mercurial chatter along with output from
... build_site.sh (and thus 'nikola build'), so if you get "Site built OK, deploying"
... then you know everything went alright and your new post is live!

Just remember to keep both your Nikola installations in sync to always be sure that the draft your are seeing on your local machine will build the same on your server.

See other posts about: