Get Started with Sinatra on Heroku

Jagadish Thaker
Share

sinatraherokuThis post will give you a brief explanation on getting started with Ruby and the Sinatra web framework deployed to Heroku. It’s important that you have basic Ruby knowledge, including an installed version of Ruby 1.9.2, Rubygems, and Bundler.

Other prerequisites are as below:

  • Basic Git knowledge
  • Your app needs to run on Ruby (MRI) 1.9.2
  • Your app should use Bundler
  • Heroku account

Set Up Your Local Workstation

To get access to the Heroku command-line client, Git distributed version control, and Foreman, install the Heroku Toolbelt on your local workstation.

Log in using your email ID and password by typing heroku command in the command shell.

$ heroku login
Enter your Heroku credentials.
Email: adam@example.com
Password:
Could not find an existing public key.
Would you like to generate one? [Yn]
Generating new SSH public key.
Uploading ssh public key /Users/adam/.ssh/id_rsa.pub

When it says ‘Could not find an existing public key’, type y to create a new ssh key. This key allows you to push code to Heroku. Using the heroku command, you can add public key in Heroku.

Getting Started

If you have an existing Sinatra app, feel free to use it. Otherwise, here’s a “Learning Ruby on Heroku” sourcefile you can use:

web.rb

require 'sinatra'
get '/' do
  "Learning Ruby on Heroku"
end

Declaring Dependencies with a Gemfile

The existence of a Gemfile tells Heroku that this is a Ruby application.

Gemfile

source "https://rubygems.org"
gem 'sinatra', '1.1.0'

Run bundle install to set up bundle on your local workstation.

Declaring Process Types with a Procfile

Foreman uses a text file named ‘Procfile’ in the root directory of your app to declare what processes need to run.

Since all Sinatra apps are Rack-compliant, we can create a config.ru file in the root of the directory and tell Foreman to use it.

Create a file config.ru:

require 'my_app'
run MyApp.new

Run it to make sure the app starts:

rackup config.ru

You might want to refer our 4-part Sinatra Tutorial to learn more.

Now, it can be added to the Procfile:

web: bundle exec rackup config.ru -p $PORT

A single process type, web has been declared, along with the command required to execute it. The name “web” has significance here, as it states that this process type would be connected to the HTTP routing stack of Heroku, and handle web traffic when implemented.

Now, you’re all set to get started with your app locally using Foreman (installed within the Toolbelt):

$ foreman start
16:39:04 web.1 | started with pid 30728
18:49:43 web.1 | [2013-03-12 18:49:43] INFO WEBrick 1.3.1
18:49:43 web.1 | [2013-03-12 18:49:43] INFO ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-linux]
18:49:43 web.1 | [2013-03-12 18:49:43] INFO WEBrick::HTTPServer#start: pid=30728 port=5000

The app will show up on port 5000. Make sure you check whether it’s working properly with a web browser, then Ctrl-C to exit.

Put the App Into Git

We now have three main elements of our application: Process types in a Procfile, dependencies in a Gemfile, and the source in web.rb. Let’s store your app into Git:

$ git init
$ git add .
$ git commit -m "init"

Deploying the App to Heroku

Creating the application on Heroku:

$ heroku create
Creating blazing-galaxy-997... done, stack is cedar
http://blazing-galaxy-997.herokuapp.com/ | git@heroku.com:blazing-galaxy-997.git
Git remote heroku added

Note: Your Heroku app name will be different from mine (“blazing-galaxy-997”).

Deploying the Code

To push our code to Heroku, we use the git push command:

$ git push heroku master
Counting objects: 6, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (6/6), 660 bytes, done.
Total 6 (delta 0), reused 0 (delta 0)
-----> Heroku receiving push
-----> Ruby app detected
-----> Installing dependencies using Bundler version 1.1
Checking for unresolved dependencies.
Unresolved dependencies detected.
Running: bundle install --without development:test --path vendor/bundle --deployment
Fetching source index for https://rubygems.org/
Installing rack (1.2.2)
Installing tilt (1.3)
Installing sinatra (1.1.0)
Using bundler (1.1)
Your bundle is complete! It was installed into ./vendor/bundle
-----> Discovering process types
Procfile declares types -> web
Default types for Ruby -> console, rake
-----> Compiled slug size is 6.3MB
-----> Launching... done, v4
http://blazing-galaxy-997.herokuapp.com deployed to Heroku
To git@heroku.com:blazing-galaxy-997.git
* [new branch] master -> master

Notice that Heroku tells us it found the web process in our Procfile. Things are working as they should.

Controlling Your Application

You now have deployed your code to Heroku. The next step is to execute a process type, by instructing Heroku to run the related command in a “dyno” – the fundamental worker process on Heroku.

You can scale your application by adding more dynos for a process type. Here’s a example of ensuring that you’ve one dyno running the web process type:

$ heroku ps:scale web=1

To check the state of the app’s dynos, use the heroku ps command which shows your app’s running dynos.

$ heroku ps
=== web: `bundle exec ruby web.rb -p $PORT`
web.1: up for 9m

It shows that 1 dyno of the app is running. With command heroku open, you can visit your app.

$ heroku open
Opening blazing-galaxy-997... done

Scaling Up

Your first web dyno for a Heroku application is free. However, if you don’t scale beyond that free dyno, Heroku reserves the right to kill the dyno after a period of non-use. You can avoid this by adding a second dyno:

$ heroku ps:scale web=2

You can go for maximum 750 dyno-hours for free for each application. Make sure you don’t run out of free monthly allowance. To scale back to one dyno:

$ heroku ps:scale web=1

Checking Out the Log

Heroku facilitates the viewinng of log files with the command heroku logs:

$ heroku logs
2013-03-13T04:10:49+00:00 heroku[web.1]: Starting process with command `bundle exec ruby web.rb -p 25410`
2013-03-13T04:10:50+00:00 app[web.1]: [2013-03-13 04:10:50] INFO WEBrick 1.3.1
2013-03-13T04:10:50+00:00 app[web.1]: [2013-03-13 04:10:50] INFO ruby 1.9.2 (2011-07-09) [x86_64-linux]
2013-03-13T04:10:50+00:00 app[web.1]: [2013-03-13 04:10:50] INFO WEBrick::HTTPServer#start: pid=2 port=25410

Console

You can run commands in a one-off dyno, such as scripts that just need to be executed once, with the heroku run command. Using it, you can launch an interactive Ruby shell ( bundle exec irb ) linked to the local terminal for testing in the app’s environment:

$ heroku run console
Running `console` attached to terminal... up, ps.1
irb(main):001:0>

irb loads only Ruby standard library by default. From it you can require some of your app files. Or it can be done on the command line:

$ heroku run console -r ./web

Rake

Similar to the console, you can run rake in an one-off dyno:

$ heroku run rake db:migrate

How to Use a SQL Database

For our sample application, you don’t need to use SQL database, but most “real” apps will need some kind of persistence. To add a free, development PostgreSQL instance you your app:

$ heroku addons:add heroku-postgresql:dev

You’ll need to add the Postgres gem to your app, by adding a line to your Gemfile as shown below:

gem 'pg'

and redeploying your application.

To redeploy your app after you make a change:

git commit -am "Added pg gem"
git push heroku master

This article really only scratches the surface of deploying a Sinatra app to Heroku. Next steps might be:

  • Make the app save state to Postgres
  • Add some javascript/css
  • Explore the seemingly endless collection of Heroku add-ons to see what services you can leverage to improve your app.

Good luck!