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
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).
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:
- A Heroku account. One can easily be obtained by visiting Heroku’s homepage and clicking Sign up.
- 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
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 commitwithout 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.
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.
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
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.
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
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
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
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.