Sinatra + Heroku = Super Fast Deployment

When I started writing for Rubysource, I soon realized that I needed a website to go with my little bio at the bottom of each article. I’ve bumbled along so far by linking to various sites that I’ve written and my Twitter page, but none of these were actually MY site.

As a result, I decided to spend some time over the weekend putting something together. I just wanted to set it up quickly, so I threw together a quick Sinatra app and hosted it on Heroku. If you haven’t used these before then it’s really easy to install them both using Rubygems:

gem install sinatra heroku

I was amazed at how quick it was to deploy a website using these two technologies – the whole process just took a couple of hours from start to finish*. Now the site is live, I thought I would write up the experience and workflow of producing and deploying a website in this manner.

  • I should add that while it only took a couple of hours to get the website up and running. It took quite a few hours after that tweaking the design and getting it ‘just right’! That still doesn’t change the fact that the bare bones of the site was up and running really quickly.

This is Manchester – We Do Things Differently Here

When I started thinking about a theme for my site, I very quickly settled on my city of Manchester. I’m really proud of coming from such a great city and wanted to incorporate aspects of it (especially the music) into a simple design. After playing around with lots of different color combinations, I settled on black and yellow, which are the city colors (the city mascot is a bumblebee.) These colors are also featured in the Factory Records and infamous Hacienda nightclub branding. I didn’t do much design work on the computer – just a few sketches with a pencil and paper and a logo design in Inkscape. Once that was done, I went straight to building the site.

Why Sinatra?

To start with I just wanted to build a one-page site, which I could have built using a plain old static html file. So why did I go with Sinatra? There were a number of reasons. The first was simplicity: I started with a single file – main.rb – using inline views:

This meant that I could develop the site rapidly in the initial stages as everything (views, styles, routes etc) were altogether in the same file. Using Sinatra also allowed me to write my views using Slim, making the markup much easier. Also, I could use a layout file that is resuable if I added any other pages in the future.

To go with my Manchester theme, I wanted to implement some quotes about the city in the banner at the top of the page that would change on each visit. This was easy to do using a little bit of Ruby, but wouldn’t have been possible with a static page. I started by writing the 3 quotes as inline views at the bottom of my main.rb file:

Then I created an instance variable in the handler that randomly chose one of the quotes:

Now, I could place this piece of code in the appropriate position in the layout:

Using Sinatra also made it easy to add some configuration options by using a configure block at the top of main.rb. This block holds any sitewide settings.

Notice the environment settings (that start with ENV) – they are used by Heroku for sitewide settings. They are easy to set up with a simple command:

heroku config:add AUTHOR=DAZ

The configure block will look for these first and if they have not been set, use the default value that comes after ||.

Sinatra also lets me implement 404 Page Not Found and 500 Error pages in just a couple of lines:

All I need to do then is create a couple of views that are shown if these errors occur:

In future I plan to build a little blog engine so that I can add a blog to the site – this will be easy since the site’s foundations already use Sinatra.

Using Sinatra also made it really quick and easy to add a contact form (more on that later). Again, I could have done this with some php that is easily found on the Internet, but I prefer using Ruby and I think that this goes to show that Sinatra can be used as the modern, Ruby alternative to PHP for producing small, dynamic sites.

Sassy Styles

Sinatra made it simple to add use Sass to preprocess the CSS. All I needed was the following line of code:

Using Sass was essential in rapidly iterating the style of the site and keeping the styles organized. I used separate files for reset, settings, mixins and a responsive layout. keeping these in separate files, made them much easier to manage. They can then be imported into the main stylesheet using the @import command:

In the settings file I used variables for the colors and fonts that I wanted to use.

I used the following technique to manage my colors:

Then in my main stylesheet.scss file I would put this line:

This meant that I could play around with which shades of colors I wanted by editing the value of the $yellow and $grey variable. I could also decide which color I wanted the banner to be by simply changing the $banner variable in the settings file. This saved me having to wade through the main stylesheet to find the the styles for the banner. I used this technique for the colors of all the major sections.

I also used mixins for repeated bits of code.

This made it really easy to use the same style of links with different color schemes in different parts of the page. For example, in the footer I wanted yellow links that are black on hover:

This all took about an hour to build a basic functioning site. The next hour was taken up sorting out the hosting.

Hosting on Heroku

Next was hosting on Heroku. Again this was easy. I created an app on their new Celadon Cedar stack:

heroku create daz4126 –stack cedar

This creates an app that can be found at http://daz4126.herokuapp.com. But I wanted my own domain, so I bought daz4126.com and then installed the Heroku Custom Domains and Zerigo addons:

heroku addons:add custom_domains:basic
heroku addons:add zerigo_dns:basic

Then I added my newly aquired domain (as well as the www. sub-domain, just in case somebody is still using it):
heroku domains:add daz4126.com
heroku domains:add www.daz4126.com

Last of all, I changed the nameservers of my registrar to point to Zerigo’s servers:

a.ns.zerigo.net
b.ns.zerigo.net
c.ns.zerigo.net
d.ns.zerigo.net

The process of updating nameservers varies and depends who you registered the domain with. Most registrars let you do this yourself online (mine did), but you might have to contact some to ask them to do it for you.

And Boom! Straight away http://daz4126.com and http://www.daz4126.com were showing my new creation.

Contact Form

I also wanted a contact form so people could get in touch. This was really easy using the Pony gem and Heroku’s free SendGrid addon for managing email delivery. Installing these simply needed the following code:

sudo gem install pony
heroku addons:add sendgrid:starter

All I needed was a form on the website that I built in Slim:

After that, it was simply a case of configuring Pony in the handler. Since the form was on the homepage, I just did a postback to the root url:

Because I’m using Heroku, the settings were all preconfigured when I installed the SendGrid addon. The ENV settings are automatically populated with a username and password for Sendgrid, so there isn’t anything else to do.

Once this is pushed to Heroku the contact form works flawlessly – feel free to send me a message!.

Adding More Content

Something else that I implemented was a simple way of adding extra content with this little piece of code:

This basically checks if there are any pages in the views folder. First it checks if there is a slim page, then for a markdown page. If it can’t find any then it shows the 404 error page. This means that I can add any new pages to the site by simply throwing a slim or markdown file into the views folder. The address of the page will be http://daz4126.com/filename. Again this makes for some rapid development – I can add pages really quickly and without having to add any more routes or controllers.

One thing that I like about this is that it makes it really easy to put together a dynamic site. With a few minor modifications this could be used to mock up a site very quickly to show clients – forget using wireframe software, just build the site up there and then in the browser!

I’m going to keep working on the site over the next few weeks and then get down to writing that blog engine (which I’ll write up as a tutorial on here). You can see the finished site here(and it’s also linked to on my bio below!) and all the code is on github.

I’d certainly recommend giving Sinatra and Heroku a go if you are looking to build a relatively simple site quickly. It is a perfect combination of speed and power, with room for the site to expand in the future.

I’d love to hear any feedback or if anyone has any thoughts on using Sinatra and Heroku for rapid development, please leave a comment below.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • http://loudcoding.com Paulo Casaretto

    Great article!
    Sinatra is very cheap and easy for something like this. I like it a lot.
    BTW, the sendgrid add-on installation is duplicated in the text.

    • http://daz4126.com/ Darren Jones

      Thanks for the feedback Paulo. I agree that Sinatra just makes stuff like this so easy to set up and implement – I love using it!

      Thanks for spotting the Sendgrid duplication – fixed now.

      DAZ

  • http://7fff.com John

    Great post. I can tell you that students I’ve had in recent courses I’ve taught would dig a screencast of this whole process — soup to nuts, starting with domain registration, DNS, getting Heroku creds, etc., etc.

  • http://daz4126.com/ Darren Jones

    Cheers John, glad you liked it.

    A screencast eh? …. I’ve never tried making one, but I think I might have a go at what you suggest, especially if you think it may be useful. What type of course do you teach?

    Not sure how my Manc accent would sound on video though!

    DAZ

  • Amit Erandole

    Could you please explain what is happening with this helper method?

    def javascripts
    javascripts = “”
    (@javascripts?([@javascripts].flatten+settings.javascripts):settings.javascripts).uniq.each do |script|
    javascripts << "”
    end
    javascripts
    end

    I understand the block but where are these instance variables coming from? I can’t parse this part:

    @javascripts?([@javascripts].flatten+settings.javascripts):settings.javascripts

    • http://daz4126.com/ Darren Jones

      Hi Amit,

      You set them in the route handlers. Like this,

      get ‘/’ do
      @javascripts = “/application.js”
      slim :index
      end

      This allows you to add javascript files on a route by route basis. Of course, you might not want to set any @javascripts, so that snippet tests if the instance varaible has been set or not. There’s also an array called settings.javascripts for global javascript files.

      I’m in the process of writing up this technique in more detail at the moment, so hopefully the post will make things clearer.

      cheers,

      DAZ

      • Amit Erandole

        That does make things slightly clearer. When is your next post coming up again? Also is it possible for you to show us how you could break out your code into separate files and modularize it? I like the single page style but would like to see the modular way too.

        And not to be annoying :) but showing how to work with ruby and javascript together with the sinatra framework would be great too.

        • http://daz4126.com/ Darren Jones

          Hi Amit,

          Not sure when the next post will be … hopefully in a week or so. Nothing annoying about those requests. In fact, it’s like you can read my mind – what you’ve asked for is almost exactly what I’m working on!

          The blog engine for the site will be modular, so hopefully that will explain how to do that.

          I’m looking at Backbone myself at the moment to try and integrate the front end JS with Sinatra a bit better, so will also try and write about that soon.

          cheers,

          DAZ

  • http://daz4126.com/ Darren Jones

    Thanks to everybody that has given feedback about this tutorial and my website by filling in the form on the site! If you want a response, either comment here or make sure you include some contact details when you fill in the contact form.

    cheers,

    DAZ

  • @ahsan_s

    Thanks for your awesome work on Sinatra. I’m still waiting for your Sinatra+Backbone.js article. Also, it’d be nice to see how one can create a basic blogging app using these technologies. Thanks again. You rock!

  • Gordon F

    Daz

    Have you worked with light weight Padrino framework built on Sinatra at all? Looks like it adds some great basic application functionality to Sinatra.

    Do you have any thoughts on this framework?

    Here is the link to it:

    http://www.padrinorb.com/

    Thanks for your input.

    Gordon Foster