I've blogged for almost 5 years now.
I'm not a really active blogger and I'm not fond of editing my blog system and themes.
So basically since 2009, I had only used BlogEngine.Net as my choice. It just works and I only need to setup once.
Everytime I want to submit new post, I use Windows Live Writer to create, edit, and publish it. So It is simple enough.

Reasons of Migration

BlogEngine.Net is built with .NET platform, so the obvious option is Windows shared hosting / vps.
Unfortunately finding a good cheap Windows shared hosting is not as easy as Linux.
I decided to use Erudeye hosting, which is based in Indonesia, I've never regretted it.
I used the cheapest shared plan which is 50k rupiahs/month. I didn't get database connection but it didn't matter because BlogEngine.Net can use xml to store blog data.

In 2013, I heard good things about Digital Ocean. They offer vps plan as low as 5 usd/month.
There is not much difference and with Digital Ocean, I can get a vps which allows for more freedom.
Actually I also have other vps, which is served by Linode. However that one is for my experiments. I don't intend to host my blog there.

One thing to consider before migrating my blog server is the fact that I want to use different blog system.
BlogEngine.Net probably works on Mono for Linux, however I really want to explore different options. I'm sure there are others blog systems which is more suited to my preference.

Why Jekyll ?

Before I choose Jekyll, I was thinking of Ghost blog, which is built with Node.js, one of my current preferred platforms.
I did choose BlogEngine.Net because it is developed with .NET and not PHP.
I was familiar with PHP during my university year, but I'm more of pro MS guy, thus I decided not to use Wordpress which I believe is a better platform than BlogEngine.Net.

I tried the early version of Ghost blog and I noticed that it uses database connection (SQLite by default). I prefer not to rely on database to store my blogs data. Not that it is bad, but my blog requirements is simple enough.
Migrating blog version which uses database may need to perform additional steps to migrate database schema.
Ghost blog is also still at early version though it is popular.

The other option is using static blog generator. It generates static HTML so it doesn't require database and it is easier to integrate with source control.
Jekyll is the most popular static blog generator. Octopress, one of other alternatives is also based on Jekyll. There is also Docpad which is built with Node.js.

Long story short, I chose Jekyll.
I like how it has more extensive documentation and the fact that I have used it before. I felt it is simple enough.
To be honest I prefer Node.js more than Ruby since I am more familiar with JavaScript.

Migration Steps

The first thing that I do is creating simple app to convert the post content from xml to jekyll .html file with YAML Front Matter, which is a relatively trivial task.
One thing to take note is I decided to use highlight.js instead of SyntaxHighlighter and Pygments. So I need to replace pre and code block via regex.

As for theme and layout I decided to create a simple one myself.
I admit I'm lacked of designer skill, so I just use few color combination and only 1 media query breakpoint. For compiling css, I use Sass.

Jekyll also has plugins to make life easier. I use the following plugins:

As for tag/category generator, I wrote it myself. Not a complicated task though.

class CategoryPage < Page
    def initialize(site, base, dir, category, posts)
      @site=site
      @base=base
      @dir=dir
      @name='index.html'
      self.process(@name)
      self.readyaml(File.join(base, 'layouts'), 'category_index.html')
      self.data['posts'] =posts
      self.data['category'] = category
      self.data['title'] = "Category: #{category}"
    end
  end


class CategoryPageGenerator < Generator
    safe true
    def generate(site)
      categories={}
      site.posts.reverse.each do |post|
        next if post.categories == nil
        post.categories.each do |category|
          unless categories.has_key?(category)
            categories[category]=[]
          end
          categories[category] << post
        end
      end
      dir = site.config['category_dir'] || 'categories'
      categories.each do |name, posts|
        site.pages << CategoryPage.new(site, site.source, File.join(dir, name), name, posts)
      end
    end
  end

Basically I iterate over all posts and store the categories and its related posts in hash, then I generate a page for every category.

Deployment

I choose git post-receive hook to automate the post publishing process.
So everytime I want to publish post I just need to commit changes and push it to my server's git location, just like deploying with PaaS providers.
This is as simple as publishing via XML RPC and Windows Live Writer, but since the current process involves git, I also get the benefits of source control.

As for post-receive bash script, the content consists of:

  • cloning the jekyll repository to temporary location
  • switch rvm
  • try to install dependency via bundler if there are changes to Gemfile
  • jekyll build
  • delete the jekyll repository in temporary location

As for automating infrastructure installation, I use puppet.
The puppet script is responsible for installing nginx, rvm, setting nginx configuration and post-receive hook, which I tested in local vagrant box.
So after spawning new Digital Ocean's droplet, I just need to run puppet script to set up almost everything.