DevZona

Rails, Heroku, AWS and other awesome technologies

Free and Fast Blogging With Octopress, Rack::Cache, Newrelic, and Unicorn

| Comments

Overview

Octopress is an awesome “blogging framework for hackers” built on top of Jekyll. It uses scripts to build static files to be deployed anywhere you want. It is really easy to build a static blog with Octopress, but there is a number of improvements that you can do, in order to make it very fast, and reliably host it for free.

Caching

As I mentioned above, Octopress builds static HTML, CSS and JavaScript from source files on your computer. Then, these static are deployed to the web server. So, if your blog is static, and doesn’t require any server-side code to generate dynamic content, why not cache all of those files? This way, all of the files will be served from Rack::Cache middleware and will never even hit app server. In order to add static files caching to your blog, add following lines to your Gemfile:

Gemfile
1
2
3
gem 'dalli'
gem 'rack-cache'
gem 'memcachier'

And code below to your config.ru:

config.ru
1
2
3
4
5
6
7
8
9
10
11
12
13
require 'dalli'
require 'rack-cache'
require 'memcachier'

use Rack::Cache,
  verbose: true,
  metastore:   Dalli::Client.new,
  entitystore: "file:tmp/cache/rack/body"

use Rack::Static,
  :urls => ["/assets", "/images", "/javascripts", "/stylesheets", "/media" ],
  :root => 'public',
  :cache_control => 'public, max-age=2592000'

Also, if your blog is hosted on Heroku, don’t forget to provision Memcachier addon.

NewRelic

I hosted my blog on Heroku using one free dyno. The problem with this is that Heroku will idle a dyno after one hour of inactivity. So, I decided to add NewRelic monitoring to my blog, and set ping with the interval of one minute from Settings -> Availability Monitoring tab. This way, I had NewRelic send a GET request to my app every minute, so that dyno never idles. Adding newrelic:

Gemfile
1
gem 'newrelic_rpm'
config.ru
1
require 'newrelic_rpm'

Additionaly, I downloaded default configuration file from NewRelic profile and added it to config/newrelic.yml. After I deployed changes above, I expected to see data in my NewRelic dashboard. However, it wasn’t the case. Whatever I did, I couldn’t get the newrelic_rpm to report the data.

Unicorn

Octopress ships with WEBrick web server by default. Since I ran only only one free dyno on Heroku, I wanted to add multi-processed web server for better handling of concurrent requests. Unicorn was the obvious choice here. Unicorn is the HTTP web server for Ruby applications that runs one master process and a specified number of worker processes. It lets your app to serve multiple concurrent requests on a single port. Configuring Unicorn with Octopress app is pretty easy. First, add unicorn gem to the Gemfile:

Gemfile
1
gem 'unicorn'

Add configuration file config/unicorn.rb:

config/unicorn.rb
1
2
3
worker_processes 4
timeout 30
preload_app true

If you are using Foreman, modify your Procfile to start unicorn when the app boots:

Procfile
1
web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb

Lastly, in order to ensure proper operation of newrelic_rpm in a forked environment, add following lines to config.ru:

config.ru
1
NewRelic::Agent.after_fork(:force_reconnect => true) if defined? Unicorn

After applying these changes, your Octopress blog should be able to handle load better, particulary, it can serve four (or whatever number of workers you specify) concurrent requests on a sinle web server instance. Incidentally, in my case, implementing Unicorn also fixed my NewRelic reporting problem: as soon as I deployed, I started seeing data in NewRelic dashboard.

Conclusion

To conclude, I showed you how you can make your Octopress blog blazingly fast with rack-cache and Unicorn. I also suggested free and reliable hosting with Heroku and NewRelic.

EDIT

As some of the commenters requested, I posted the source code for Gemfile, Gemfile.lock, Procfile, config.ru and config/unicorn.rb in this gist. Happy coding!

Comments