As of right now's blog hosting isn't complete, so we'll use GitHub Pages, but when it's ready I'll come back and update this post for

Prerequisites: rvm, ruby, bundler

Check to see if you have rvm, ruby, and bundler installed.

In the terminal try to switch to ruby version 1.9.3 by entering rvm use 1.9.3. If that succeeds you'll see a message like Using /Users/aj/.rvm/gems/ruby-1.9.3-p374 which means you have rvm and ruby installed. Then try entering bundle. As long as you do not get a message similar to command not found: bundle, then bundler is installed.

Follow Installing Ruby on Ubuntu (and then come back) if you think you need to install either rvm + ruby or bundler.

Notes for Experts

This tutorial is geared for both noobs and experts. For your convenience there are blocks of script without so much explanation or unneccessary commands.

Notes for Newbies

In this tutorial we're really cranking it to 11 so you can get a blog up quickly.

A brief synopsis is given here, but the steps will be explained as you go.

  • ls show files (except dotfiles) in the specified (or current) directory
  • ls -a show all files (including dotfiles)
  • bundle install installs ruby gems
  • bundle exec runs a command from a ruby gem
  • git clone copies a repository (meaning a database)
  • git add lets git know that a file should be committed in the next commit
  • git commit -m "blah blah" saves changes to the git repository
    • You should always change the blah blah to something meaningful to you
  • git push pushes commits to a remote repository (such as github)
  • pushd changes into a directory
  • popd goes back to the directory you were before you last did pushd
  • mv renames (or moves) a file or folder
  • rm removes a file
  • rm -r removes a folder

THE MOST IMPORTANT RULE for beginners: DON'T TYPE so much!. Typing is the #1 reason for typos. You're using a computer, which is created to decrease the number of things a person has to remember to do. After you type the first letter or two of a file or folder hit the <tab> key a few times and it will either fill out the name of the file for you or give you a list of matching files (or give you no list if you have a typo or the file doesn't exist yet) It's almost impossible to have a typo if you're using <tab>. Don't type things out all the way unless you know you have to.


  • dotfiles and dotfolders are hidden files and folders whose names begin with .
  • repository is a type of database that is used (mostly) for storing source files
  • database generally refers to some sort of magic that stores information
  • source file a easy-for-humans-to-read file format (that can be compiled)
  • compiled file an easy-for-computers-to-read file format
  • directory is a folder. The two words are interchangeable.
  • folder is a directory.

Ruhoh is like Amish Friendship Bread

In order to host your blog on you do, in fact, need to be using ruhoh (surprise!).

A ruhoh blog is a lot like Amish Friendship Bread, you get a little starter pack with all the indegridents you need and then you get to add stuff and grow it on your own.

The first thing you'll do is use git to clone the "starter pack". The "starter pack" is called blog-v2, meaning blog, version 2 (the second version of ruhoh).

For the Experts

Note: Even though inuition tells you to rename blog-v2 to something of your own choosing, you can leave it for now (for copy-paste's sake) and we'll change it later.

pushd ~
git clone 'git://' 'blog-v2'
pushd blog-v2
git checkout "2.0.alpha"
bundle install

For the Beginners

First go to your home directory which is something like /home/aj/, but is referred to as ~ for short.

pushd ~

Now double check that you are there (you'll see something similar to /home/aj/, but with your name instead of mine (which is AJ).


Take a look in your directory to see what files and folders currently exist (it'll be stuff like Documents, Pictures, Movies, etc)

ls .

Now clone the starter pack into your home (which is where you are right now)

git clone 'git://' 'blog-v2'

Look again in your home and notice the new folder blog-v2

ls .

Did you see it? Good. Look inside of it.

ls ./blog-v2/

Now that you've see what's in it, change to that directory (and note that the ./ prefix is optional, it's assumed by default, so this time we'll leave it off)

pushd blog-v2/

Again, check where you are (it'll be something like /home/aj/blog-v2)


And again, look at the contents of the directory. (again, leaving off the ., since it's optionall and assumed by default)


Before we go further I want you to notice something special about this blog-v2 directory that was cloned from github. Run ls again, but with the argument -a you will see all files and folders, including the hidden dotfiles and dotfolders (the ones that begin with . as the first character of their name).

ls -a

You should notice that there is a folder .git/.

Note: / is used as a suffix to denote that the particular item is a folder, not a file, but it's okay if the / folder suffix is missing. That said, it's best to always type the / folder suffix when entering commands because commands that only work on files will complain if they see a trailing / and you'll know immediately if you made a mistake.

The next step is to get the 2.0 branch of ruhoh. This will remove all of the committed (saved) files of the master branch (which are currently in the directory) and replace them with the files and folders of the 2.0.alpha branch.

git checkout "2.0.alpha"

Note: All of the git commands will only work in a git repository, meaning a folder that has a hidden .git/ folder in itself or a parent (meaning that if ~/blog-v2/.git/ exists, I can also run git commands from ~/blog-v2/themes/twitter/ because git will check in ~/blog-v2/themes/twitter/, fail, then check ~/blog-v2/themes/, fail and finally succeed when checking~/blog-v2). The exceptions to this rule aregit clone(which creates a local copy of a repository) andgit init(which adds the.git/` folder to the current directory).

If you try to run commands outside of a git repository, you'll get a message like fatal: Not a git repository (or any of the parent directories): .git.

The last part in this step is to install ruhoh's ruby gems.

bundle install

Note: All of the bundle only work in a ruby app - meaning a folder that has a Gemfile - otherwise you will get an error such as Could not locate Gemfile. So if you get that error, you're not in the right directory. Use pwd to see where you are and ls -a to check what files are there.

If you get the error ERROR: Gem bundler is not installed, rungem install bundlerfirst. you should run ruby --version then rvm use default and then ruby --version (if the version of ruby changed, you may not have been using the correct version of ruby at first). After that do as it says and run gem install bundler and, finally, try again.

Note: My instructions may become out of date, so check out before you get too far along in this process.

Note: I put instructions on upgrading ruhoh in the appendix.

Feel empty inside - and feel great about it!

To run your blog in preview mode

bundle exec rackup -p 9292

rackup starts a webserver written in ruby. The command will not "finish". It will continue to run until killed. (If it ran and then just quit, it wouldn't be very good at serving web pages)

Because of the configuration files that ruhoh created earlier, rackup knows how to dynamically compile the files of your blog on-the-fly.

Now open http://localhost:9292 and you should see next to nothing (an empty blog with a theme, but no posts). Hurrah!

Next go back to the terminal and <ctrl>+c once or twice to quit rackup.

To compile your blog (production mode)

bundle exec ruhoh compile

Note: I finally explain about bundle exec in the appendix

And now you can serve the compiled version of your blog (in the compiled/ folder) with any static site server (so if you have a server, rsync -avhP it over and take a look).

pushd compiled/
python -m SimpleHTTPServer 3000

Python's SimpleHTTPServer module also runs a webserver, just like rackup, but it's written in python.

Because it doesn't read the configuration created by ruhoh, python's webserver will just serve files from wherever you start it. In order to serve you blog, you must start in from the compiled/ directory.

Now open http://localhost:3000 and you shouldn't at all be surprised by the near-nothingness in your view.

Go back to the terminal and <ctrl>+c once or twice to kill python so you can take a look at what you've created.

Other webservers might require you to move the compiled/ folder to a different location and or edit a configuration file that tells it where files are located.

Anyway, now it's time to back out of the blog directory.

ls compiled
ls blog-v2

As it turns out you could open this static site in a browser even without a server

On Mac OS X:

open blog-v2/compiled/index.html

On Ubuntu Linux:

xdg-open blog-v2/compiled/index.html

However, it probably won't look so pretty (it will be more just text) because without the server it can't find the additional files that tell the page what it should look like. vs

At this point it's important to note that the instructions for compiling your blog are slightly different based on how you intend to host it.

I host mine using the blog subdomain of Similarly, ruhoh will host your blog at

One day you may have your own server hosting your blog and you might want to mount it at the pathname /blog at

In that case you'll need to vim config.yml and make sure that base_path is not commented and points where you need it. For example: base_path: "/blog"

Set vim to be your default editor

If you don't know what vim is, then you'll need to watch [vim for people who would rather not use vim][vim-docs] and then set your editor to be vim by running this command.

sudo update-alternatives –config editor

Select the first vim.

Publish your nothingness!

There's a reason I'm telling you to do this before you actually create a post is that there's a one-time setup process that I don't want to get confused with the posting process.

The name of your blog should be your github pages url.

My github name is coolaj86. Because my github name is coolaj86, my github repos url is automatically Also because my github name is coolaj86, my github pages url is automatically

The name of my blog should therefore be

For the love of all that is holy, DO NOT use (change it to your github pages url).

Create a repository for yourself on github such as

  1. Get logged in to GitHub
  2. Create a repository with the name
* if you created it by the wrong name, you can rename it
  1. Copy the https:// url of the repo
* mine, for example, is

Now for the work part.

mv ~/blog-v2/ ~/
pushd ~/

# Repositories are for source files, not compiled files
rm -rf compiled/

# tell git to ignore "complied/"
echo "compiled" >> .gitignore
# tell git to ignore all lock files (such as Gemfile.lock)
echo "*.lock" >> .gitignore

# create a new branch called "blog" (we'll never go back 2.0.alpha)
git checkout -b blog

# The starter pack has the origin for ruhoh, which isn't for you
git remote rename origin ruhoh

# Your origin should be the repo you created earlier
git remote add origin PASTE-YOUR-GITHUB-GIT-URL-HERE

# take a look at all the things
git status

# add color, if you haven't already
git config --global color.ui true
git status

# add everything new (this command should be used very rarely)
git add .

# see what changed
git status
git push origin -u blog

Note: If you can't figure out that PASTE-YOUR-GITHUB-GIT-URL-HERE was supposed to be replaced with the url you copied earlier you're either up too late, drunk, or you should just call it quits and move to learning something else because this is not your thing.

Your first post (and every post after it)

As exciting as it may be to show your friends that your blog is using the same twitter-bootstrap theme every blog uses these days, it would be a lot more exciting with some posts. Am I right or am I right?

This is how you create a blog post:

git checkout blog
bundle exec ruhoh posts new "My First Post"
vim posts/

Write something explaining that you're starting a blog or copy an old post.

You should end up with a file that looks something like this:

title: "My First Post"
date: "2013-02-14"
  - raves

Today is a good day.

Here's the **proof**:

  * I'm alive and well.
  * I started my own static blog.
  * And then I found five dollars!

What a *great* day!

It should be obvious that "My First Post" should be the title of your post and each post should therefore be different.

FYI: You can leave categories empty, but it's fun to have a few such as 'rants' (when you're complaining about something), 'raves' (when you're praising something), '42' (for ponderings about life, the universe, and everything), and 'boring' (for the super exciting stuff you don't want anyone to know about). These show up on the categories page of your blog.

If you'd like a quick markdown primer, see An introduction to Markdown

And once you've got your whatever going

git status
git add posts/
git status
git commit -m "added my first post"

At this point if you get a message about git config and git commit --amend, you should follow those steps.

git status
git push origin blog
git status

Uniquely you

Edit each of these for yourself (i.e. using vim to open and edit the files). If you're not sure what something means, it probably doesn't appy to you.

  • data.yml
    • the things that need to change here should be pretty obvious
    • put in any text for the field author (it's the title of the indented collection below it, not a field for you to put something)
  • config.yml (probably only needs a few things changed)
    • production_url should be something like
    • I recommend that you change teh permalink to be /posts/:title/ because I often change the categories of my blog (and that ruins the idea of a permalink)
  • ./widgets/comments/config.yml
    • sign up for a disqus account if you want to use this
  • ./widgets/analytics/config.yml
    • sign up for google analytics if you want to use this

Create a disqus account (takes about 15 seconds) and update the comments config.yml

Create a google analytics account (basically just linking it to your gmail account)

Season. Taste. Repeat.

After you've edited the files (assuming you're still in the ~/ folder):

git status

You should see that at least data.yml has changed. Now you need to add and commit those files.

If you just type git add (with a trailing space) and hit <tab> a few times you should see the list of files that you can add. At the very least, if you type the first few letters of the path of the file and hit <tab>, it will fill it out for you. For example:

git add config.yml
git add widgets/comments/config.yml

And then commit the files.

git commit -m "updated configuration files"

Set up your Gravatar

  1. Go to
  2. Put in the same e-mail you use for github and click Get your Gravatar
  3. Follow the Instructions

Hosting with ruhoh

Continue with these instructions: Hosting ruhoh on Github Pages

not working yet, don't follow with these instructions

  1. Take a left and turn at
  2. Click on Authenticate with GitHub
  3. Authorize
  4. If you didn't get a gravatar you'll have an abnormally huge cat image that takes up way too much space... so go back and fix that.
  5. Name your blog whatever you want such as
  6. click update
  7. click compile
  8. You may have to wait a bit, but eventually your blog will exist

Put in your domain name (i.e. and then go update the DNS for your CNAME to point to at your registrar. (I use


I feel like there ought to be text between headers... even if it's just a meaningless self-reference.

Updating ruhoh

If you dare to pull the latest updates to the ruhoh blogging software (the bundle exec ruhoh xyz stuff) you can do so by executing

git fetch upstream
git pull upstream "2.0.alpha"

# NOTE: one day that will change to
# git pull upstream "2.0.beta"
# or probably maybe even straight to
# git pull upstream "2.1"

However, if you're at all faint of heart, I'd recommend following the age-old adage of if it ain't broke, don't fix it until you have a particularly compelling reason to perform an upgrade.

bundle exec

In case you're wondering, the reason for all of this bundle exec is to run little ruby apps that only exist in the ruhoh-created directory.

This is advantageous because you can have not only different versions of ruhoh for each user on the computer, but also for each blog by that user. Since you probably don't have many blogs you could probably tell bundler to install ruhoh in your home directory... but I don't know how to do that.

Oh, and I'm blogging without internet at the moment, so I can't look it up.

By AJ ONeal

If you loved this and want more like it, sign up!

Did I make your day?
Buy me a coffeeBuy me a coffee  

(you can learn about the bigger picture I'm working towards on my patreon page )