Matt Gemmell

Blogging With Octopress

3 min read982 words

It’s been almost two years since this blog last changed significantly, and in that time I’ve become a bit dissatisfied with it for a few reasons:

  1. WordPress is excellent, but it’s over-featured for what I need, and its PHP/MySQL guts are opaque. I don’t really like the idea of all my writing being inside a big database either; it’s a single point of failure, and that makes me uneasy.

  2. Despite using various caching plugins (WP-supercache, W3 Total Cache, DBCache Reloaded), the site still became very unresponsive during the several fireballs I’ve had.

  3. I’ve become increasingly invested in a philosophy of simplicity and portability. I do all my writing in the Markdown format, for example, and I value software that’s laser-focused and as purposeful as possible (that’s why I do most of my work in BBEdit).

For all these reasons, I’ve decided to make a change: this blog is now entirely static HTML, or is “baked” as the term seems to be.

The system I’m using to generate the blog is called Octopress by Brandon Mathis, which is a framework around Jekyll. You can run it wherever you like (locally, or even on your server), and it will generate an entirely static web site for you, and even rsync it to where you’re hosting from.

If you’re wondering about whether to “bake” your own blog or site, I can recommend these three posts by Brent Simmons on why you should consider it. I can also highly recommend Octopress as the means of doing it.

A few points of note:

  • I now use Disqus for comments. It’s an excellent service, and free. They can import comments from your WordPress (or other) blog, and those comments will persist if your new permalinks are the same as the old ones (as they ought to be), and naturally they support Akismet, Gravatar, and all manner of social media integration. The admin/moderation dashboard is excellent too. Really, give them a try.
    [Update: comments are now switched off. I still recommend Disqus if you do want them!]

  • I exported all of my existing WordPress posts to suitable Markdown files using exitwp. I tweaked the script a little to not perform any HTML-to-Markdown conversion whatsoever, so I could preserve my already Markdown-formatted posts with their existing paragraph breaks etc.

  • The visual design of this blog is just the default Octopress theme. I think it’s attractive and very readable, and don’t see much reason to change it. It’s all about the content, after all. It also has a mobile equivalent built in.
    [Update: This blog now uses my customised version of Aron Cedercrantz’s BlogTheme.]

  • Octopress knows about Twitter, Google Analytics, Google Plus and various other services, and has built-in integration with them. One of the main things that have impressed me about Octopress is how it seems to have the same opinion as I do regarding what’s needed and what’s superfluous.

  • It also includes a preview server for local staging, which will regenerate the site on-the-fly as you make changes.

  • This is a moderately large blog (there are about 930 posts spanning several years, cross-linked across various categories). On this machine (3.4 GHz i7, 16 GB, SSD), a full generation takes about 1 minute and 15 seconds.

  • If you want to work extensively on a single post and view it in the preview server, long regeneration times can be a pain. Octopress’ rakefile lets you isolate a single post so that only that post will be generated locally, for a quick testing cycle. To isolate a post, use:

1
rake isolate[path/to/post.markdown]

Then when you want to re-integrate all posts to do a full generation, use:

1
rake integrate
  • If you want to use the wonderful MarsEdit blogging app on OS X with Octopress, you can! Dan Weeks wrote a script for that.

  • If you’re configuring your own Octopress blog, you might be interested in tweaking your server for maximum performance. I’m using Apache2, with the “worker” MPM.

My config block in apache2.conf is as follows:

1
2
3
4
5
6
7
8
9
<IfModule mpm_worker_module>
  StartServers 2
  MinSpareThreads 25
  MaxSpareThreads 75
  ThreadLimit 64
  ThreadsPerChild 25
  MaxClients 150
  MaxRequestsPerChild 0
</IfModule>

And, importantly, I’ve set up the server to send appropriate cache-expiry headers using the site’s root .htaccess file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#### CACHING ####
ExpiresActive On
ExpiresDefault A3600

# 1 MONTH
<FilesMatch "\.(ico|gif|jpe?g|png|flv|pdf|swf|mov|mp3|wmv|ppt)$">
ExpiresDefault A2419200
Header append Cache-Control "public"
</FilesMatch>

# 3 DAYS
<FilesMatch "\.(xml|txt|html|htm|js|css)$">
ExpiresDefault A259200
Header append Cache-Control "private, must-revalidate"
</FilesMatch>

# NEVER CACHE
<FilesMatch "\.(php|cgi|pl)$">
ExpiresDefault A0
Header set Cache-Control "no-store, no-cache, must-revalidate, max-age=0"
Header set Pragma "no-cache"
</FilesMatch>

I’m sure there will be some rough spots as with any redesign, and feel free to get in touch to point them out, but overall I’m very, very happy indeed. The site should be more responsive under load, and it’s eminently portable, requiring nothing but a dumb web server.

As a final aside, if you’re looking for an excellent VPS host to put your own blog or site up on, I highly recommend Linode.

And now that’s entirely enough blogging about blogging, for another year or two at least.

Footnote: Eight days after I wrote this post, I published another article called SEO for Non-dicks. The newer post was simultaneously fireballed, linked from .net magazine, Hacker News, Marco Arment’s blog and many other places on the web, including countless tweets. That post alone had 35,000 page-views over the course of three days, and this blog as a whole had 55,000 page-views over the same period.

During that entire time, it continued to load instantly – even a few minutes after the Daring Fireball link went up – and my server (Apache 2 on Ubuntu via Linode) handled the traffic effortlessly and with plenty of resources to spare. I couldn’t have asked for a better field test. Thanks, Octopress.