Deploying a Sinatra app to Heroku

Preface

This post is an expansion on a demo I gave to the Carthage Computer Science Club, and the notes recorded on that demo.

Some command may not run correctly (specifically gem and bundle) if they’re run as a standard user, and may need to be prefaced with sudo if you’re using OS X or Linux.

Most of the information relayed here can be found in Heroku’s dev center, and more specifically the Getting Started with Ruby on Heroku article (which almost all of the content here is taken from).

Assumptions

The main assumption here is that you have an existing Sinatra application named app.rb that you can run by running ruby app.rb, and that it’s kept in a directory used only for it an related resources, and not just your documents directory.

This also assumes that you’ll use Sequel, a simple database toolkit/ORM for ruby, as your main database interface.

Getting ready to deploy

Before you can deploy to Heroku, you need two things:

  1. A Heroku account. One can easily be obtained by visiting Heroku’s homepage and clicking Sign up.
  2. The Heroku Toolbelt. Which can be downloaded at https://toolbelt.heroku.com.

Once you have both a Heroku account, and the Heroku Toolbelt installed, you can run heroku login in your terminal, where you’ll be prompted for your account information. Once you’ve finished this, the heroku command line application can manage your applications for you.

Preparing your application to be deployed

Using Git

Heroku deploys using git, a popular version control system. As such, to be able to deploy your application you need to turn it into a git repository.

To do so, navigate to your application’s directory and run the following commands:

  • git init. This creates a new git repository in the current directory.
  • git add .. This tells git that you want to add all files in the current directory, and all files in subdirectories (recursively) to the next commit. A commit is a snapshot of your project at a certain point in time, with a message attached to it.
  • git commit -m "init". This makes a new commit to your git repository, with the message “init”. If you want to write a longer message, run git commit without the -m "init" part, which will open your default text editor, just save the file, and close the editor to finish your commit.

Some other configuration files

Heroku also needs you to have two more files: a Procfile which tells Heroku how to run your application, and a Gemfile which tells Heroku what gems your project uses.

The Procfile

Your Procfile is going to be relatively uninteresting, and almost the same as anyone running a Sinatra app on Heroku:

web: bundle exec ruby app.rb -p $PORT

Provided that your application is called app.rb. Change as needed.

What that says is that you’re going to be running one process, a web process, and that you want that process to run bundle exec ruby app.rb -p $PORT, which says run your application on the port Heroku gives you, and run it using the bundle environment you’ve been given.

The Gemfile

Your Gemfile is going to be somewhat interesting. It tells Heroku what gems need to be installed for your application to run. For a simple Sinatra app that has no dependencies, your Gemfile should look something like this:

source "https://rubygems.org"
# This should be the same as the version of Ruby you have installed locally
ruby "2.0.0" 

gem 'sinatra'

Once you have that, you should be able to run bundle install locally without problem. If you don’t have the bundle command, you may need to install it using gem install bundler.

Deploying your application

If you’ve done everything above, you can now send your application to Heroku.

The first thing you need to do is tell Heroku to create a new application for you. You can do that by running 

heroku create

NOTE: This requires you to be in a git repository. If you aren’t, you’ve just created a Heroku application without attaching it to a local project, and will have to manually attach it. My suggestion is that you don’t run heroku createoutside of a git repository.

Calling heroku create will add a new remote location to your git repository so that you can push to Heroku. To do that (which will deploy your code), run 

git push heroku master

After Heroku does its thing (specifically installing your gems and running your application), you should be able to visit it. To do that easily, just run heroku open, which will open your application in your default browser.

If there are any errors, you can read you application’s log by running heroku logs.

Potential errors with deployment

Because you’re probably attempting to deploy an existing app, you could run into some problems here, especially if you’re using a database. Make sure you’ve included all the gems your using in your Gemfile, and you’re not using a database right now.

Using a database

Getting a database

Heroku provides a small free PostgreSQL database to all applications if they ask for it. The default database has a row limit on it, but for development it should work fine.

To give your application a PostgreSQL database, you need to run 

heroku addons:add heroku-postgresql:dev

This command will output several lines, one of which should look like Attached as HEROKU_POSTGRESQL_RED. Remember the color you’re given.

Heroku recommends using a DATABASE_URL variable to store your database’s location, but by default doesn’t promote any database to that config variable. To promote the development database, run heroku pg:promote HEROKU_POSTGRESQL_RED_URL where RED is the color given when you added PostgreSQL to your application.

Telling your Sinatra app about the database

To start using Sequel in Sinatra, you need the sinatra-sequel gem and a database driver. Locally, it’s probably easier to use a sqlite3 database for development.

To get started, you should add the following to your Gemfile:

gem 'sinatra-sequel'
gem 'sqlite3'

And in you should have database capabilities included in your application now:

require 'sinatra'
require 'sinatra/sequel'

configure do
    DB = Sequel.connect('sqlite://database.db')

    # DB setup here
end

# Sinatra routing here.

However, if you try to deploy this to Heroku, you’ll have problems. Heroku won’t compile the sqlite3 gem.

To fix this, you need to specify that sqlite3 is only for your development environment, and pg, the PostgreSQL gem, is only for your production environment. Change your Gemfile to match:

gem 'sqlite3', :group => 'development'
gem 'pg', :group => 'production'

You’ll also need to start using bundle install --without production instead of bundle install now, unless you can install the pg gem locally (there are occasionally problems).

You’ll also need to change your DB line to use Heroku’s DATABASE_URL variable over your sqlite url for the connection. Doing that is fairly easy and takes advantage of overloading:

DB = Sequel.connect(ENV['DATABASE_URL'] || 'sqlite://database.db')

You should now be able to push and have everything go swimmingly at this point.

Leave a comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: