Learn Ruby on Rails Book

Deploying the application on heroku

PostgreSQL database setup

Heroku uses the PostgreSQL database.

When our application is deployed to heroku then our application will be running in production mode.

Installing and configuring "PostgreSQL" in a personal laptop can be tricky. So here is what we are going to do. We will use sqlite3 gem for the development and for the test environment. We will use pg gem in production environment. In this way we do not need to install PostgreSQL in our laptop.

Modify Gemfile to use gem sqlite only in development and test environment. In the below line note that we have added group.

1gem 'sqlite3', '~> 1.4', :group => [:development, :test]

Now let's add pg gem for production.

1gem 'pg', :group => [:production]
1bundle install

Heroku setup

The first step in setting up heroku is to sign up for Heroku. Then check to see if your system already has the Heroku CLI installed.

1heroku --version

This will display the current version number if the heroku command-line interface (CLI) is available.

If you get an error then install the Heroku CLI.

Once we’ve verified that the Heroku command-line interface is installed, we need to use the heroku command to log in.

1heroku login

We will be redirected to authorize our account.

Finally we need to use "heroku create" command to create an application. In this case heroku will choose a random name for our application.

1heroku create

We will see the output something similar to this.

1Creating app... done, ⬢ agile-everglades-72910
2https://agile-everglades-72910.herokuapp.com/ | https://git.heroku.com/agile-everglades-72910.git

The name of the application will be different for everyone.

Setting up buildpacks

1heroku buildpacks:set heroku/nodejs --index 1
2heroku buildpacks:set heroku/ruby --index 2

Let's see the list of buildbacks we have.

1$ heroku buildpacks
2=== agile-everglades-72910 Buildpack URLs
31. heroku/nodejs
42. heroku/ruby

As we can see above we see both "nodejs" and "ruby" in the list of buildpacks. The order of the buildpacks matter so please ensure that the order is as shown above for your case.

Making Sidekiq work with Heroku

  • First we need to have the heroku-redis addon for our project. In order to use an addon, we need to verify our account using a credit card. Ultimately the credit card is used to verify that the user is not a bogus user. Since it's a free addon, the credit card won't be charged for usage. If we don't have a verified account, then we can't add the redis addon and thus won't be able to directly make sidekiq work in heroku!

  • Assuming we have a verified account, the next step is to add heroku-redis to our project. Two ways to set it up:

    • From the heroku website, goto resources section, and choose heroku-redis from the addons section.
    • Or run the following from your projects root: heroku addons:create heroku-redis:hobby-dev
  • After setting up the addon, add the following to your Procfile. If you don't understand what a Procfile is, then refer the detailed docs from heroku:

1web: bundle exec rails s -p $PORT
2worker: bundle exec sidekiq -e production -C config/sidekiq.yml
  • Next step is to scale our dyno to use both the web and worker:
1heroku ps:scale web=1
2heroku ps:scale worker+1
  • Sometimes our active jobs gets enqueued and not get processed in heroku. To avoid that, make sure you have successfully completed the above steps and also add the following under your production key in config/database.yml:
1  url: <%= ENV['DATABASE_URL'] %>
  • [Optional][Rare Case] Sometimes the jobs even after doing the above steps, gets enqueued in heroku without processing. Weird right? Then we can invoke the job from our Task model as follows, which hopefully should fix it:
1  after_commit :log_task_details, on: :create
  • You can view the sidekiq logs, or your project logs to be more accurate, using heroku logs -t from your projects root, once deployed.

Viewing Sidekiq dashboard in browser

This is an optional step, which you can use, if you need to view the sidekiq dashboard via browser. Add the following to your config/routes.rb:

1require 'sidekiq/web'
2
3Rails.application.routes.draw do
4  Sidekiq::Web.use Rack::Auth::Basic do |username, password|
5    ActiveSupport::SecurityUtils.secure_compare(::Digest::SHA256.hexdigest(username),
6                                                ::Digest::SHA256.hexdigest(ENV['SIDEKIQ_USERNAME'])) &
7      ActiveSupport::SecurityUtils.secure_compare(::Digest::SHA256.hexdigest(password),
8                                                  ::Digest::SHA256.hexdigest(ENV['SIDEKIQ_PASSWORD']))
9  end
10  mount Sidekiq::Web, at: '/sidekiq'
11  # rest of the routes would reside below this

We have set our app to allow viewing sidekiq logs via /sidekiq path. But we authenticate the users who can view it, using two env variables(ideally it should be rails credentials). So we need to set up those to config env variables in heroku website under Settings -> Config Vars tab.

1SIDEKIQ_USERNAME : some_user_name
2SIDEKIQ_PASSWORD : some_pass_word

That's it. Now we can view the dashboard using the /sidekiq path by providing the credentials you have set.

Setting up Heroku for Deployment

Now let's deploy the application to heroku. Let's execute following command to deploy our application to heroku.

1git push heroku master

To see how the deployment is progressing or to debug the deployment issue we can tail the log using following command.

1heroku logs -t -a agile-everglades-72910

We need to manually migrate the database.

1heroku run rails db:migrate -a agile-everglades-72910

To see the newly deployed application execute following command.

1heroku open

Setting up Auto-Deploy

Log into heroku and go to the overview page of the deployed application. Click on "Deploy" tab.

Scroll to the bottom, and we will see a button that says "Enable Automatic Deploys". Click on that button and provide github information and then heroku will display message "Automatic deploys from xxx are enabled".

Now anytime code is pushed to the branch that is enabled heroku will automatically deploy the latest code from that branch.

Heroku Commands

To run rails console of the deployed application.

1heroku run rails console -a agile-everglades-72910

To check the logs of the application.

1heroku logs -t -a agile-everglades-72910

To migrate the database.

1heroku run rails db:migrate -a agile-everglades-72910

Setting up Heroku pipeline

Heroku pipelines allow us to have a review app for each pull request. This is immensely useful in testing. We no longer need to pull down all the changes and run the application locally to see the application in action.

Here are the instructions to set up review apps for PRs:

Let's rename the deployed application to have the word "production" in its name. The new name of the application will be "zamazon-production-1873".

1heroku apps:rename zamazon-production-1873 --app agile-everglades-72911
  • Login at www.heroku.com.
  • Visit https://dashboard.heroku.com/apps.
  • Click on "New" pull down menu and then select "Create new pipeline".
  • Pipeline name "zamazon-pipeline".
  • Select for your repository name and then click on "Connect".
  • Then click on "Create pipeline".
  • Now click on "Enable Review Apps".
  • Check "Create new review apps for pull requests automatically".
  • Choose a region "United States".
  • Click button "Enable Review Apps".
  • Now send a pull request.
  • Once you send a pull request then a few seconds later you will see there will be a message that says "Deploying the application".
  • Once the application is deployed then we will see a button that says "View deployment".
  • It means now we are getting a new URL for each pull request.