The Situation: You built a Sinatra application using SQLite3 as your database and it works perfectly on your local computer. You are excited and want the world to see it in all its glory! You decide to deploy.
The Problem: You see this post on the Heroku DevCenter: You cannot use sqlite on Heroku.
The Solution: Below are the 10 steps I went through to reconfigure my Sinatra application so that it could use SQLite3 in development locally and PostgreSQL in production on Heroku.
Remember throughout this process: commit and commit often to save your progress (or, conversely, so you can revert!).
10 Steps to Deploying on Heroku
1) Add a Procfile - In your top-level directory, add a file named “Procfile” with the following command:
web: bundle exec rackup config.ru -p $PORT
This says that you want to run a web process with the command on the port that Heroku gives you, using the bundle environment given. The “rackup” command to find the “config.ru” file should make sense since it is how we start Rack-based frameworks like Sinatra.
2) Modify Gemfile and Delete Gemfile.lock
In your Gemfile, add the PostgreSQL gem to the main list of gems:
gem 'pg'
But specify that the SQLite3 gem is only for development:
group :development do
gem 'sqlite3'
end
Then delete the existing “Gemfile.lock” file and re-bundle in terminal:
bundle install
Why not include both gems in the main list? Heroku would reject my push if the ‘sqlite3’ gem was in the main list. But, when working locally for development, there were no issues keeping the ‘pg’ gem in the main list. This was my solution.
3) Create a config/database.yml File
In the config folder, create a file called “database.yml”. Add the following to configure the specifications of your database in development and production:
development:
adapter: sqlite3
database: db/development.sqlite
host: localhost
pool: 5
timeout: 5000
production:
url: <%= ENV['DATABASE_URL'] %>
adapter: postgresql
database: mydb
host: localhost
pool: 5
timeout: 5000
I learned a few things about these options. The “pool” is the number of simultaneous connections that your database can handle and I chose to be explicit, although Heroku defaults this to 5. The “timeout” is the permitted time to establish a database connection and is measured in milliseconds (i.e., 5000 is 5 seconds).
4) Modify config/environment.rb
In the config folder, modify the “environment.rb” file. Add the following to specify the location of your production database on Heroku:
configure :production do
db = URI.parse(ENV['DATABASE_URL'] || 'postgres://localhost/mydb')
ActiveRecord::Base.establish_connection(
:adapter => db.scheme == 'postgres' ? 'postgresql' : db.scheme,
:host => db.host,
:username => db.user,
:password => db.password,
:database => db.path[1..-1],
:encoding => 'utf8'
)
end
For my peers in Learn Verified, the above should look familiar to the setup for specifying our sqlite database.
Beginner Tip: Pause, Breath, Learn About Heroku: At this point, your Sinatra application is almost configured for Heroku. I highly recommend pausing and learning about Heroku by going through their Getting Started With Ruby learning module. This will get you to install and be familiar with the Heroku Toolbelt - also it’s fun!
5) Make Your Heroku App
In your top-level directory, create the Heroku app by entering the following command in terminal:
heroku create your-app-name
In my case I entered heroku create sightseedc-sinatra and it generated the URL https://sightseedc-sinatra.herokuapp.com/.
6) Push Your Application Files to Heroku
In your top-level directory, push your entire application to Heroku by entering the following command in terminal:
git push heroku master
Checkout your application live on Heroku by entering in terminal:
heroku open
There’s an error!?!? This is OK. See below.
7) Expect an Error, Get the PostgreSQL Addon
Get the PostgreSQL addon by entering the following command in terminal and keep track of the response provided:
heroku addons:create heroku-postgresql:hobby-dev
This gets you the free Heroku hobby-dev database and provides the Heroku URL for your database. In my case, I received: HEROKU_POSTGRESQL_CRIMSON_URL
8) Add .env File
In the top-level directory, add a file called “.env”. In that file, set the environment DATABASE_URL key equal to the response Heroku gave you from the addon (see above Step 7):
DATABASE_URL=HEROKU_POSTGRESQL_CRIMSON_URL
Everytime the application hits ENV[‘DATABASE_URL] in “config/environment.rb”, it will insert the above value and properly reach the location of your PostgreSQL database on Heroku.
9) Migrate and Seed Your Database, Save and Push Again to Heroku
In the top-level directory, assuming you have migrations and seed data, run the Heroku versions of rake tasks to migrate and seed your database:
heroku run rake db:migrate
heroku run rake db:seed
Save and push the updated application up to Heroku:
git add .
git commit -m "my app for deployment on Heroku"
git push heroku master
10) Enjoy Your Live Application!
Checkout your live application using:
heroku open
Email the URL to everyone you know!
For those interested in reviewing or comparing code: - Heroku app: SightSeeDC - Git repo: Original SQLite3 version - Git repo: Heroku PostgreSQL version