June 2, 2015

Building Rails Apps and Deploying to Heroku Cloud with Jenkins

Who should read this article?
If you are interested in continuous integration or love to use the best tools available to get the most out of the development process, or an if you are an organization looking to make the build and release process smoother. This article will demonstrate the power of Jenkins for building and deploying Ruby on Rails Applications.

Some of the prerequisite knowledge to get the most out of this article:

  • Basic knowledge of RVM and how to install Ruby and Ruby on Rails using RVM
  • Experience with Getting a Rails application up and running
  • Knowledge of Bundle and Rake commands
  • Knowledge of how to install and configure different components on development environment
  • Working knowledge of Heroku Toolbelt for Linux

Different Platforms

Jenkins
Jenkins is a great CI tool used by thousands of companies across world for automating build processes, continuous integration, and automated deployments. Jenkins helps organizations automate every aspect of the development and saves precious time of developers.

To learn about Jenkins, please visit: https://jenkins-ci.org/

Heroku
Heroku Cloud/Heroku Platform (or simply Heroku) is a platform as a service (PaaS) that enables developers to build and run applications entirely in the cloud. When Heroku started in 2007 it only supported Ruby; however, it currently supports several programming languages, such as Java, Node.js, Python and PHP among others.

To learn more about Heroku, please visit: https://www.heroku.com/

Ruby On Rails
Ruby on Rails, or simply Rails, is an open source web application framework written in Ruby.

To learn about Rails, please visit: https://rubyonrails.org/

Install all components required to run a Rails application if you haven’t already; including any third party library, database softwares, or development libraries. This guide does not include steps to install those components on the target system. This guide expects that system is capable of running system when a fresh checkout of platform code is made. Please ensure all required components are pre-installed on target system.

This article is going to use an Ubuntu-based system for demonstrations and expects readers to have at least basic knowledge of Git, Github and Linux command line.

Setting Up Your Jenkins Environment

Installing and configuring on Ubuntu
● wget -q -O – https://pkg.jenkins-ci.org/debian/jenkins-ci.org.key | sudo apt-key add –
Wget-Output

● sudo sh -c ‘echo deb https://pkg.jenkins-ci.org/debian binary/ > /etc/apt/sources.list.d/jenkins.list’
Jenkins CI
● sudo apt-get update && sudo apt-get install jenkins
Install-Jenkins-2

You should now have Jenkins CI up and running on the target machine; you can access it with:
https://<JENKINS_HOST>:8080/

Install Ruby with RVM
Ruby needs to be installed on target system before we can start building our Ruby or Ruby on Rails project with Jenkins.
In order to install RVM and Ruby using RVM, switch to jenkins user and install RVM and Ruby:
first install the required dependencies for Ubuntu:

sudo apt-get install libgdbm-dev libncurses5-dev automake libtool bison libffi-de
sudo apt-get update

Then, use the following command to install RVM and Ruby:

sudo su – jenkins
curl -L https://get.rvm.io | bash -s stable

Jenkins Install

source ~/.rvm/scripts/rvm
rvm install <<YOUR_RUBY_VERSION>>

Install Ruby Message

Once you have installed, you need to create a profile and bashrc file and add the rvm executable paths to it. If you like, you can download .bashrc and .profile used in preparation of this article from following Gists:
● Bashrc : https://gist.github.com/ravishtiwari/9b7f27d8f1794af9b451
● Profile : https://gist.github.com/ravishtiwari/c62cdee835d607469f51
Download the above files and save them to following location:
● Bashrc => ~/.bashrc
● Profile => ~/.profile

Install Required Plugin with Jenkins
Go to your Jenkins Plugin manager (https://<JENKINS_HOST>:8080/pluginManager/) and
install following plugins (from ‘Available Plugins’):

Jenkins Install Plugin

Configure Jenkins Globals
After installing these plug-ins, we will need to configure them in order to use them with our build jobs. Go to the Jenkins Configurations page https://<JENKINS_HOST>:8080/ and configure:

Jenkins Configure

  • Heroku – Default API Key
  • Add a Git installation
  • Configure
  • Git user.name
  • Git user.email
  • And GitHub Webhook
  • Configure global Extended E-mail Notification Template
  • Add SMTP settings for E-mail Notification

Jenkins-Configure-Global-Email

 

Install Heroku Toolbelt
Install Heroku Toolbelt on System from https://toolbelt.heroku.com/

SSH Keys for Github and Heroku
Generate SSH key for Jenkins, Jenkins will use this key to access our Github and Heroku repos. Switch to Jenkins user using: sudo su – jenkins and generate a new SSH key.
If you do not how to do this, follow this Github guide: https://help.github.com/articles/generating-ssh-keys/
Building with Jenkins
Go to your Jenkins home, and create a Free Style project {{Home->New Item}}

Add a Name for the Project and click create

create-project

Source Code Management
1. Choose ‘Git’
configure-project
2. Add ‘Credentials’ for Git,

  • Select Kind as: SSH Username with private key
  • Provide user name and Git Private Key for Jenkins to use

Configure-Git-Keys

Build Triggers

  • Configure Appropriate Build Triggers
  • I would prefer a nightly build, something like:
H 00 * * *
Each line consists of 5 fields separated by TAB or whitespace: MINUTE HOUR DOM MONTH DOW

configure-project-build

 

Build Environment

  • Set Build Environment to appropriate Ruby Version:
such as : 2.1.4

2.1.4

 

Configure Build

  • Inject required environment variables for build process, If required environment variables are not set at this stage, build will fail to execute, because it won’t able to detect the environment for running rake
  • Select “Execute Shell” from ‘Add Build Step’ drop down and add following commands as build script:
    gem install bundler
    bundle install
 rake db:migrate
    rake test

configure-project-build

After successfully configuring all these steps, we should have a running build with, something like this:

build-output-tests

Post Build Email Notifications

To get notifications after each build, which I am sure can be of immense use, you will need to “Configure Email notifications” as a “Post Build Task”

  • Add email ids who should receive notifications for builds
  • Configure trigger: Triggers are used to trigger email notifications when specific condition is met, for example, we can have separate email to Successful and Failed Builds

To configure Email notifications, click on Post Build Action dropdown, and select “Editable Email Notification” option
jenkins17

and then click on “Advanced Settings…” button to configure Trigger for email notification. Remember, with Editable Email Notification, you can configure different emails for different situations.
Configure-Email-Notification-2

Automated Deployment to Heroku after build
We can configure our Jenkins build to deploy automatically to Heroku Cloud after each successful build. We can use combination of shell commands + utilities from Heroku Plugin for Jenkins to do our deployments. Let see how we manually deploy our app to Heroku Cloud:

  • Add Heroku Git origin to git checkout
  • Turn ON the maintenance mode before pushing code to Heroku
  • Push the git changes to Heroku
  • Run any required process, such as DB migration, assets precompile etc
  • Scale the process
  • Turn OFF maintenance mode for app

Now, let’s configure same with Jenkins.

Configure Post-Build Actions
For build success first select “Execute script only if build succeeds”
select following action from post-build action drop down

  • Heroku: Maintenance Mode
    turn on maintenance mode for app
    post-build-turn-on-maintenance
  • Execute a set of Scripts: add heroku git remote to project and push changes to heroku,
 such as:
heroku git:remote –ssh-git -a Heroku_App_name
git push -f heroku HEAD:master
    post-build-add-heroku-git-origin
  • Heroku: Set Configuration
    and set any configuration vars required by Heroku app
  • Heroku: Run Process
    run post deploy task for app, such as rake db:migrate
    post-build-add-heroku-run-processes
  • Heroku: Scale Process
    if required scale your app
    post-build-add-heroku-scale-process
  • Heroku: Restart
    restart your app if required
  • Heroku: Maintenance Mode
    turn off maintenance mode for app
    post-build-turn-off-maintenance

Save the changes, hit “Build now” to verify settings
For a successful build and deployment on Heroku Cloud, we should get the following deploy log as part of the build output:

heroku-deploy-log

If you have configured email triggers, you will see following text as part of build log:

send-email-post-build

 

Let’s Review
Jenkins is a great and versatile tool. Jenkins has plugins for all aspects of the build process. Rails Applications can benefit from such vast availability of plugins and APIs readily available for Jenkins. There are a couple CI tools that are specific to Rails, but Jenkins is very vast and versatile, and it can be easily configured and used to take care of Rails Build and Deploy process, and this is why we strongly recommend Jenkins. We have successfully used Jenkins CI from small to Large Scale Rails Applications.
If you have any query related to this article, or want to explore options to use Jenkins for Building your Ruby, Ruby on Rails, or any other application, please let us know and we will help your team get the maximum out of your build process.