Starting a Blog

Why a static generator

I’ve been thinking about writing a blog for some time now. I wanted to keep it simple and make it load as fast as possible, so instead of a Wordpress or Joomla I wanted to use a static site generator. The benefits are clear:

  • Simplicity.
  • The page doesn’t need to be generated in server side for every request (even with caching, nothing beats static content)
  • No database required.
  • Clear separation of content and theme.
  • Content in markdown, Blackfriday flavour (text files).
  • Since the content is in text files, the whole site can be in source control.
  • Since the content is in text files you can create your content from any text editor, including Vim.
  • Easy to customize a theme or create one from scratch.
  • Security (if everything is static and there’s no database, there’s less less moving parts and a smaller attack surface)
  • Since it’s all static files it can be deployed to a CDN, even for free, so it also loads faster.
  • You can configure a webhook between your source control and your CDN so that every new post triggers a build and publishes on the CDN.

Why Hugo

I did some research on the state-of-the-art in static site generators. The most popular one by far is Jekyll, and Octopress, based on it, is also quite popular. Both are ruby-based applications. There are some other Ruby-based like Middleman and other less popular. Others are based on Python, like Pelican, Cactus, Hyde and others. There are many popular NodeJS based ones like Hexo, Metalsmith, Wintersmith, Roots and others. There PHP, Perl, C++, .NET, Java, Scala, and even Haskell and Ocaml based static site generators.

Yet all of them have the same problem: When you add new content you have to regenerate the whole site, which means that the build time is increasingly high. Every time you add a new post it will take longer to build, and the build times are not negligible.

Yet there is a one of them, written in Go, that is rising in popularity: Hugo. The best feature of Hugo is its performance. It can build a site with thousands of posts in a matter of seconds. That’s right, it takes an average of 1ms to build a single post. It also has a lot of additional features, like support of Ace and Amber templates, both of which are very similar to the very nice syntax of Jade or Slim.

Now, installing Ruby it’s a nightmare, as there are too many ways to do it, and there can be multiple conflicts with different versions and what not. Python can also be problematic, specially between Python2, Python3 and pypy, although not as much as Ruby. Installing NodeJS-based applications is also not as smooth as it should, since old versions tend to break, altough it seems to have improved with the newer versions. But with a go application, sure, you can compile from source, but there’s no need. As an example, with Hugo, you just download the executable, add it to the Path and it works.

First steps with Hugo

In order to make Hugo generate the scaffolding for your static site, assuming on this example that the name of the containing folder for your project will be blog

$ hugo new site blog

And you would create a new post using

$ hugo new post/welcome.md

That will generate a markdown file with a front matter header. Front matter allows to configure all the little details for that post/page. Hugo supports TOML, YAML and JSON for Front Matter, although TOML is the default.

You can use one of the many available themes for Hugo, customize it or even build your own.

Hugo supports Go templates, Ace templates and Amber templates. The syntax of the first one is probably not the best syntax I’ve ever seen for a templating engine, and that includes JSP… But Ace and Amber are actually pretty good, lean and elegant, inspired by Haml, Jade and Slim.

If you’re creating your own theme, in addition to a templating engine you’d also probably want to use a CSS preprocessor like Sass, Less or Stylus, and you may also want to add an Alt-JS language like Coffeescript for your some more advanced features in your site. You can easily integrate Grunt or Gulp with Hugo so that, combined with Hugo’s LiveReload you can have instant feedback on your changes. But that could be a post on its own.

You can start hugo to watch for changes and render drafts with

$ hugo server -w -D

You’ll be able to see your blog in http://localhost:1313

Deploying to a CDN

There’s a number of deployment options:

  • Build the site locally and FTP/SCP to a VPS where you can serve it with any server, like nginx, caddy, apache
  • Build directly on your VPS, a variaton of previous option.
  • Use Github as your source control and deploy to github pages, by creating a gh-pages branch.
  • Deploy to a CDN (since all the content is static)

The best option hands down is the last one, and there are many ways of having automated deployments to a CDN for free.

There are lots of CDN providers, and you can use any of them to generate the site in your computer and publish the generated static files. But some of them have support for a Continuous Delivery (CD) workflow. The idea is to set up a webhook with your repo (usually the integrations are with Github and/or Bitbucket) so that every time you push a new commit it triggers a new build so they run hugo to rebuild and publish automatically your site on the CDN. Some CDN’s that I’m aware of which have support to build sites with hugo (and other static site generators) with a webhook are

Of course, you could also use any provider of CI/CD as a service to create a webhook with Github or Bitbucket, build your site with hugo and publish wherever you want. This guide explains how to set up CD with Wercker and Github. Even better, this guide explains how to set up CD with Github or Bitbucket directly with Netlify, and this other guide explains how to do the same with Aerobatic.

Since it´s all static files, using a CDN will make it load really fast. And since we have a webhook, it will publish automatically any change.

Analytics

Now that we have our blog up and running we’ll probably want to track how many visitors it receives, and some statistical information like geographical location of our visitors, how many time did they spend, on which pages, what browser are they using, and so on. The obvious choice is Google Analytics, but if we want to own our own data, we can use a self-hosted solution like Piwik. We will need a VPS for that, a small one will do.

Comments

Since it’s a static blog, unlike other solutions like Wordpress or Joomla, or hosted options like Medium or Blogspot, Hugo doesn’t come with a commenting system. The most popular option in this space is Disqus, but if we want to keep control of our data we’ll also look for a self-hosted solution. The creator of Hugo wrote Kaiju, which is a commenting system written in Go, but a popular option is isso, written in Python.

Conclusion

In conclusion, once you have everything set up you could publish a new blog post from literally everywhere. You just need either your favourite text editor and git, or a web browser where you could edit directly a Markdown file on Github or Bitbucket. You can literally use also the first option on an Android phone with Termux, editing with Vim, commiting and pushing with git to Github or Bitbucket and it would be automatically published. You may have worked on a new post and there are just a few things to do to complete it, you can mark it as a draft, and resume work in your phone. And undraft it as soon as it’s complete.

More Reading