Migrating from Ghost to GitHub Pages

I have been a fan of Ghost blogging platform ever since I discovered it. It has a great balance between convenience such as the ease of setting it up and simplicity like markdown editor for text.

However, as good as Ghost is, for now, I am only concerned with blog writing and everything else that Ghost offers is not of critical importance. Thus, to avoid the recurring AWS bills, I decided to give a go at setting up the Ghost equivalent on GitHub pages which is free and see how it will work out.

Let's go through the tutorial of how to do that by first examining building blocks involved in setting up the free blog.

Overview of building blocks

GitHub Pages is nothing more than your well-familiar GitHub repository. It is a free feature provided by GitHub. To illustrate how it works with an example, you can just create a new GitHub repository, checkout to gh-pages branch, upload an index.html file there and voila, your website will be available to see at https://{username}.github.io/{repo_name} serving the index.html file.

Jekyll is a static site generator based on Ruby. You simply set up the new Jekyll site, edit the posts there via Markdown and once the site is ready, you issue a command that generates static files of your website. These static files can then be uploaded to your GitHub Pages repository which will host and serve them to visitors.

Jasper is a theme for Jekyll site. It is the copy of Ghost official theme Casper.

Travis CI is a continuous integration service. We will use it to generate the static site files and upload to appropriate GitHub repository when our site is updated.

Step 1 - set up Jekyll's theme Jasper

Go to Jasper and fork the GitHub repository. This is our launch base from now on. We will publish and edit new posts from here. All our site configurations will be done from this repository as well.

For starters, open _config.yml and change all instances of string ramkarolis to your own GitHub username. All other settings are optional so just experiment with them as you wish. I would pay particular attention to author's info, Google Analytics identifier, and site description.

Step 2 - create personal GitHub page

We need to create an additional empty directory called {username}.github.io. The generated static site files will be uploaded here and served at https://{username}.github.io. We can think of it as a deployment repository and in the configuration files it is called just such DEPLOYMENT_REPO.

Step 3 - configure Travis CI

First and foremost, sign up to Travis CI. Then go to your profile, sync GitHub repositories and activate the newly created one i.e. {username}/jasper. This will trigger Travis CI to do its job (generate static files) upon each push to GitHub repository.

Then configure Travis CI so that it gets write access to your newly created repository. Do so by going to your repo on Travis CI and adding GIT_EMAIL, GIT_NAME and GH_TOKEN environment variables. You can get GH_TOKEN by generating a new personal access token from GitHub Tokens.

Now, each time you push to {username}/jasper repo, it will trigger Travis CI to execute bundle exec rake deploy task declared in the Rakefile. The deploy task generates the static files and uploads them to {username}.github.io repository which hosts the site.

Step 4 - write a new post and migrate old ones

Now test the new setup by adding a new post at _posts and push it to {username}.github.io/jasper repository. This will trigger Travis CI which will then upload the newly generated static files to our deployment repository {username}.github.io.

If all went well, go to https://{username}.github.io and check the new site. Overall, pretty easy right?

Now, if you have more than one blog from the previous Ghost blog, I would use jekyll_ghost_importer tool to migrate all the posts. Works flawlessly.

Step 5 (optional) - setup custom domain

Setting up a custom domain is extremely easy. Go to your deployment repository settings, type your custom domain and you are halfway done. Then configure DNS settings using instructions provided by GitHub.

Final considerations

There is a key issue that I am not particularly fond of in this deployment. I would much rather prefer to just have one personal repository {username}.github.io and avoid the jasper repo altogether. However, I haven't found a neat way to achieve this when serving the site from a personal repo.

If it were a project repository, you can select the branch which GitHub uses to serve the website enabling to have all your Jekyll files at master branch and uploading the static site to gh-pages branch. For user website i.e. {username}.github.io that option is not allowed and only what is uploaded on the master branch is served.

If you find a neat way to go around this limitation, please share!

EDIT (2017/04/08)

I moved back to Ghost platform as in the end the Jekyll+GitHub+Travis CI setup proved to be too cumbersome. It's ok for occasional blogging or hosting a website for a side project. But for my personal blog needs Ghost turned out to be much more productive and thus I'll stick with it from now on.