Rails on Maui

Programming in Paradise

Updating My Blog to Octopress With Jekyll 2 and Discourse for Comments

This weekend I made the ambitious move to using Discourse.org for my blog and also upgrading Octopress to the latest version which supports Jekyll 2.0. Here’s my notes, so that you can evaluate if you want to do either of these, as well as how to do this efficiently.


What motivated me to update Octopress? The main reason was that Octopress finally got upgraded from a beta version of Jekyll to Jekyll 2.x.

What motivated me to migrate comments to Discourse?

  1. I already wanted to create a forum for my website, so integrating blog comments seemed worth pursuing. This is what BoingBoing uses for its blog articles. Click on the “Discuss” link below any BoingBoing article and get taken to the Discourse topic for that article.
  2. I wanted to be able to have more engaging conversations with my programmer friends on the topics which I’m blogging about.

What’s super cool about doing the conversion?

  1. Discourse will automatically create topics for each of your blog posts. You can see that here: http://forum.shakacode.com/category/blog
  2. Discourse can import the Disqus comments from your blog!

    What this looks like on the blog, http://www.railsonmaui.com

    What this looks like on the forum, http://forum.shakacode.com:

Updating Octopress

Googling for upgrading octopress gave me my own article as the second match. It’s always a great reason to blog and have your notes indexed by Google!

I ran into one difficult issue with the upgrade. The issue was the very frustrating:

bin/ruby_executable_hooks:15: stack level too deep (SystemStackError)

How did I solve the problem?

Naturally the first thing to do is to google the error message. That was not particularly helpful.

Since I assumed that this problem would be pretty specific to my Octopress site, I guessed that the issue was related to a rogue Jekyll plugin.

I moved all my plugins that were not part of standard Octopress into a /plugins_removed directory, and then added back my plugins one at a time. That helped me narrow down the issue to the jekyll_alias_generator plugin, which sets up redirects when you change the URL of a published blog articles.

Then I clicked on the Issues icon for the jekyll_alias_generator and searched for stack level too deep and BINGO!

And here’s the solution: Stack level too deep error #14, which is to replace lines 73-75 in alias_generator.rb with this code:

(alias_index_path.split('/').size).times do |sections|
    @site.static_files << Jekyll::AliasFile.new(@site, @site.dest, alias_index_path.split('/')[1, sections + 1].join('/'), '')

Update: rather than using the AliasGenerator plugin, use: jekyll/jekyll-redirect-from

Another issue I hit was that I had a few template files that were using

layout: nil

This results in errors like:

Build Warning: Layout 'nil' requested in atom.xml does not exist.

This got changed in the recent version of Jekyll to use null, like this:

layout: null

So grep your files for layout: nil and change those to layout: null.

Installing Discourse for Blog Comments

This is well described in the following articles. I’ll give you my specific steps below.

  1. Setting up discourse on Docker: github: discourse/docker and discourse/docs/INSTALL-digital-ocean.md. You can probably do fine on a $10/month plan. The trickiest parts is to be sure that you do every step very carefully. It’s very easy to make one typo and to then slow the process down!
  2. Embedding Discourse in Static Sites is the primary source of information on converting from Disqus to Discourse for your blog comments.
  3. Discourse plugin for static site generators like Jekyll or Octopress: Specifics for Octopress and Jekyll.

Once you configure your Discourse site to import your blog articles, you’ll have to wait a bit for the rake task to run. It’s great being able to kickstart the content of the forum with one’s blog articles!

Discourse Configuration

The configuration of Discourse for blogging is super easy.

  1. Configure the following settings, taking note that:
    1. The urls are to your blog and include the subdomain, like www.railsonmaui.com.
    2. The embeddable host does not include http://
    3. The feed polling URL does include http://

  2. I added a category called “Blog”.
  3. I created a user called “disqus” for users not found in the Disqus comment import.

Octopress Discourse Comments Setup

  1. Remove or comment out your Disqus setup in your /_config.yml file:
    # Disqus Comments
    # Removed as support for Discourse comments added
    # disqus_short_name: railsonmaui
    # disqus_show_comment_count: true

    Note, I first commented it out, because I toggled this on and off as I was ensuring that the comment migration worked correctly, and none were missed.

  2. Add the plugin contained in discourse_comments.rb to your /plugins directory. This plugin will append a DIV to your posts like this:
    <div id="discourse-comments"></div>
    <script type="text/javascript">
      var discourseUrl = "#{@site.config['discourse_url']}",
          discourseEmbedUrl = "#{@site.config['url']}#{@site.config['baseurl']}#{url}";
      (function() {
        var d = document.createElement('script'); d.type = 'text/javascript'; d.async = true;
        d.src = discourseUrl + 'javascripts/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(d);
  3. Note that the display of comments only works on your live website, due the fact that the Discourse server checks the source of the request for the comments (per the above image of the configuration).

Detailed instructions for importing your Disqus comments into Discourse

The following instructions will allow you to import the comments from Disqus, along with creating associated users for those comments. This is a GREAT way to kickstart the forum.

  1. Download an XML backup of your Disqus comments by logging into your Disqus dashboard. The URL is like https://youraccount.disqus.com/admin/discussions/.
  2. That should bring you to the Discussions tab. Then click the Export sub-tab. It should look like this: You’ll have to wait a few minutes for the creation email. I then saved the file to my ~/Downloads directory.
  3. Ssh to your docker instance
    ssh root@XXX.XXX.XXX.XXX
  4. Get into your docker instance.
    root@forum:~# cd /var/discourse/
    root@forum:/var/discourse# ./launcher ssh app

    You’ll see this message:

    Welcome to Discourse Docker
    Use: rails, rake or discourse to execute commands in production
  5. Sudo to discourse:
    root@forum:~# sudo -iu discourse
    discourse@forum:~$ cd /var/www/discourse
    discourse@forum:/var/www/discourse$ bundle exec thor list
  6. Then you need to copy the XML file you downloaded from Disqus that contains an archive of your comments. The easiest way to do this is to scp the file from some place accessible on the Internet. What I did was to scp the file from my local machine to my Digital Ocean machine, and then from my Digital Ocean machine to the Docker container. Here’s an example:

    On your local machine, with the XML file (XXX.XXX.XXX.XXX is the ip of your droplet):

    scp ~/Downloads/railsonmaui-disqus.xml root@XXX.XXX.XXX.XXX

    Then inside of your docker container:

    discourse@forum:/var/www/discourse$ scp root@XXX.XXX.XXX.XXX:railsonmaui-disqus.xml .

    That puts the file railsonmaui-disqus.xml in the current directory.

  7. Run the thor command:
    discourse@forum:/var/www/discourse$ bundle exec thor disqus:import --file=railsonmaui-disqus.xml --post-as=disqus --dry-run
    /var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activerecord-4.1.6/lib/active_record/connection_adapters/postgresql_adapter.rb:898:in `rescue in connect': FATAL:  database "discourse_development" does not exist (ActiveRecord::NoDatabaseError)
    Run `$ bin/rake db:create db:migrate` to create your database
      from /var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activerecord-4.1.6/lib/active_record/connection_adapters/postgresql_adapter.rb:888:in `connect'

    The problem is that we need to specify the environment, as is standard with Rails apps:

    RAILS_ENV=production bundle exec thor disqus:import --file=railsonmaui-disqus.xml --post-as=disqus --dry-run

    That command does the trick and gives you a nice message indicating what it will do once you remove the --dry-run flag.

    discourse@forum:/var/www/discourse$ RAILS_ENV=production bundle exec thor disqus:import --file=railsonmaui-disqus.xml --post-as=disqus --dry-run
    Creating Favorite RubyMine Tips - Rails on Maui... (8 posts)
    Creating Octopress Setup with Github, Org Mode, and LiveReload - Rails on Maui... (3 posts)

    Once you verify, run:

    RAILS_ENV=production bundle exec thor disqus:import --file=railsonmaui-disqus.xml --post-as=disqus

    This creates the comments and the users. Creating the users surprised me as I didn’t know that the Disqus export contained the users’ email addresses. So this script ends up triggering activation emails to all those users!


This is all pretty neat! Not only did I get my new forum populated with some content, but I also created users who commented on my posts in the past. I’m hoping I can engage in more meaningful discussions regarding the technologies that I blog about with my own forum. Please do sign-up for the forum so you can comment and receive periodic updates of what gets posted! Or just sign up when you want to post a comment. :-)