This 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: email@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.
If you have an existing Sinatra app, feel free to use it. Otherwise, here’s a “Learning Ruby on Heroku” sourcefile you can use:
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.
source "https://rubygems.org" gem 'sinatra', '1.1.0'
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
require 'my_app' run MyApp.new
Run it to make sure the app starts:
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/ | firstname.lastname@example.org: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 email@example.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
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 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
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
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:
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
- Explore the seemingly endless collection of Heroku add-ons to see what services you can leverage to improve your app.