How-to : Hosting Your Static Sites On Heroku

Once I’ve finished migrating this blog, the next task that I need to resolve is finding a good place to host it. As you might notice, I don’t need anything but a simple web server. I could just pick any free hosting, point my domain to it, and call it a day.

But that’s definitely not blogging like a hacker, my friend.

I was looking for something more subtle than conventional hosting. I’ve spent a considerable amount of time trying to find some good hosting. If you’re looking for good free hosting with no ads, there is only one that I can recommend: serversfree.com. They’re so good that it almost sounds too good to be true, and they offer a lot more features than paid hosting could provide. I did look into a few offers from local hosting providers in Malaysia, and for 1GB storage with 1GB bandwidth, they’re asking for about RM50 per year. Triple that, and you’ll get 2GB of storage with 10GB of bandwidth. Like that’s going to happen.

I could always rent a Virtual Private Server (VPS), but that’s definitely overkill just to host a bunch of static files. I don’t think it’s an effective investment since I don’t blog that much, and there are too many things I need to think about, and managing my VPS isn’t one of them.

While serversfree.com works fine and is ridiculously better than any local paid hosting, let me just list down things about it that kept me worried:

1. I am skeptical about free stuff.
2. I am more concerned about speed and availability than in point 1.
3. Above all, I don’t want to use an FTP app to publish my blog.

LFTP might solve point number 3, but I don’t think I want to do it. Plus, it does not solve point number 2. Right now, I’m ready to spend some fortune, but:

Giving away a dollar effectively is harder than to make a dollar. - Steve Jobs

Out of luck, I stumbled upon an alternative that caught my attention: Heroku. Despite hearing about it before, I didn’t realize its potential for free blog hosting until I read a post by fellow developers.

So, what exactly is Heroku?

It’s a cloud Platform as a Service (PaaS) that eliminates the need for managing underlying hardware and software. Their philosophy revolves around maximizing developer productivity by minimizing unnecessary steps. I was immediately intrigued by this approach.

Developer productivity is our battle cry, at the core of everything we do. Why require three steps when one will do? Why require any action at all when zero steps will do?

That was their philosophy. Enough, I’m buying.

Welcome to PaaS.

To get started, I signed up for a Heroku account and downloaded the necessary toolbelt.

Fire up the terminal, and type:

$ heroku login

You’ll be asked for a password, and Heroku will take care of everything. Now it’s time to create your app, web app, or anything you would like to call it:

$ heroku create (app name)

With Heroku’s reliance on Git for deployment, it’s essential to familiarize oneself with Git basics

$ git init /* to initialize git repository, 1 time only */
$ git add . /* fastest 'way' to adds a change to staging area */
$ git commit -m "First commit." /* commit to repository */
$ git push heroku master /* deploy to Heroku */

However, there’s one crucial step remaining. Heroku needs to recognize the app and assign the appropriate framework. Since my blog is built with Nanoc, a Ruby-based static site generator, and I can use Rack (a Ruby webserver) to serve it, I created a Gemfile and a config.ru file. These files, placed in the site’s root, allowed Heroku to identify it as a Ruby app.

Fill the Gemfile with this :

source 'https://rubygems.org'

gem 'rack-contrib'
gem 'heroku'
gem 'shotgun'
gem 'adsf'
gem 'nanoc'
gem 'kramdown'

If you know what you’re doing, you don’t even need all the gems.

and config.ru with this :

require 'bundler'
Bundler.setup
Bundler.require
require 'rack/contrib/try_static'

use Rack::TryStatic, 
    :root => "output",  # static files root dir
    :urls => %w[/],     # match all requests 
    :try => ['', 'index', '/index'] 
run lambda { [404, {'Content-Type' => 'text/html'}, ['Not Found']]}

With the Gemfile populated with the necessary gems and the config.ru file configured for Rack, I pushed the changes to Heroku:

$ git push heroku master

The web app was now live and ready to be viewed:

$ heroku open

But we’re not quite finished yet. Since I have my domain for blogging, I decided to use it with Heroku:

$ heroku domains:add pali7x.com

Just like that, I associated my domain with the Heroku app.

Now it’s just a matter of pointing your domain to Heroku. This might sound easy enough, but unfortunately, I ended up submitting a ticket for technical support for my domain registrar because their A records won’t accept a duplicate domain with different IPs. I solved this problem by switching to a third-party DNS. Maybe I’ll switch my registrar as well in the future.

To simplify the domain resolution and ensure a consistent experience, I made use of the rack-rewrite gem. By modifying the Gemfile and the config.ru file, I added the necessary code to redirect requests to root domain.com.

Modify Gemfile and add this :

gem 'rack-rewrite'

and config.ru as well :

require 'rack/rewrite'

use Rack::Rewrite do
  r301 %r{.*}, 'http://domain.com$&', :if => Proc.new {|rack_env|
      rack_env['SERVER_NAME'] == 'www.domain.com' || 
          rack_env['SERVER_NAME'].include?('herokuapp')
    }
  end

After committing the changes and pushing them to Heroku, the setup was complete.

So, what’s next?

As mentioned earlier, hosting this blog on Heroku is free, as long as scaling is not a requirement. Heroku’s pricing is based on resource usage, and they provide a helpful calculator to estimate monthly costs. Even with their free plan, I found it more than sufficient for serving static files to a moderate number of visitors.

While Heroku might not be everyone’s preferred choice, embracing this platform can save a significant amount of money. Now, I need to find a solution for hosting my images and consider optimizing my blog further.

Posted August 20, 2013

Tweet