Approx 8 minutes read

OpenShift is Red Hat’s Platform-as-a-Service (PaaS) that allows developers to quickly develop, host, and scale applications in a cloud environment similar to Heroku. OpenShift also supports deploying of application with simple git push just like Heroku. OpenShift supports a variety of technologies through use of cartridges, including Java (Wildfly, JBossEAP, Tomcat), PHP, Node.js, Python, Perl, MySQL, PostgreSQL, MongoDB, Jenkins, Cron, and JBoss xPaaS Services (Fuse, BPM Suite, BRMS, Data Virtualization, Aerogear, and more).

Why OpenShift?

The free version of OpenShift, OpenShift Online, has many advantages over free tier of Heroku:

  • If application is not accessed for an hour on Heroku, web dyno goes to sleep mode making the next request take up to 30 seconds to serve leading users to abandon the site visit. OpenShift’s idling time is 24 hours and, as of my personal experience, it takes around 10 seconds for next request to serve.
  • The free database tier on Heroku allows only 10,000 rows to be stored. There is no such limitation in OpenShift.

  • Heroku lacks persistent storage, its file system is read only and hence it doesn’t allow file upload from application, e.g. user avatars. OpenShift provides 1GB of persistent storage with free tier which can be used to store the assets.

  • OpenShift provides SSH access to control the application which is lacking in Heroku.

  • OpenShift also provides port-forwarding feature which lets one connect to the database using locally installed client.

  • OpenShift provides support for deployment hooks which can be used for running custom scripts before or after deployment.

Getting Started

Sign up for a free account of OpenShift at https://www.openshift.com and set up the rhc client tool as documented here.

Create the Ruby Application

Create the Ruby application by logging in to web console or via rhc client tool by issuing following command:

1
$ rhc app create myapp ruby-2.0 postgresql-9.2

Here myapp is the name of the application, and ruby-2.0 and postgresql-9.2 are the cartridges. Once the application is created, it will output the git repository path. Take a note of this path as this would be used to push the code to OpenShift.

Setup git remote

Navigate to the existing rails application directory and add the OpenShift remote as below:

1
$ git remote add openshift ssh://[email protected]/~/git/myapp.git/

Now pull the remote changes by issuing following command:

1
$ git pull openshift master

It will result a conflict in config.ru. Just abandon the content created by OpenShift. Below is the default config.ru file for the reference which is generated by rails:

1
2
3
4
# This file is used by Rack-based servers to start the application.

require ::File.expand_path('../config/environment',  __FILE__)
run Rails.application

Modify Gemfile and .gitignore

OpenShift uses an old version of bundler and hence if ruby version is specified in Gemfile, as shown below, it breaks.

1
2
3
4
5
source 'https://rubygems.org'

ruby '2.0.0' # Causes problem in OpenShift
 
gem 'rails', '4.0.8'

Also, as recommended by OpenShift, using their Ruby mirror http://mirror.ops.rhcloud.com/mirror/ruby/ can quicken the installation of gems.

And at last, if application was deployed on Heroku, it’s high chance that database.yml was added to .gitignore file as Heroku creates it’s own database.yml file during deployment. If it’s the case, remove the database.yml line from the .gitignore file.

Database configuration

Add following section in database.yml file:

1
2
3
4
5
6
7
8
9
production:
  adapter: postgresql
  encoding: unicode
  pool: 5
  database: <%=ENV['OPENSHIFT_APP_NAME']%>
  host: <%=ENV['$OPENSHIFT_POSTGRESQL_DB_HOST']%>
  port: <%=ENV['$OPENSHIFT_POSTGRESQL_DB_PORT']%>
  username: <%=ENV['OPENSHIFT_POSTGRESQL_DB_USERNAME']%>
  password: <%=ENV['OPENSHIFT_POSTGRESQL_DB_PASSWORD']%>

Deployment hook

To run the database migrations, create a deployment hook by adding following lines to .openshift/action_hooks/deploy file:

1
2
3
4
5
6
#!/bin/bash

pushd ${OPENSHIFT_REPO_DIR} > /dev/null
echo "Running migrations"
bundle exec rake db:migrate RAILS_ENV="production"
popd > /dev/null

In above script, pushd will put the current working directory on the directory stack and switch to the directory path in the ${OPENSHIFT_REPO_DIR} environment variable and popd will retrieve the directory from the stack and set it again as the current one. This is because bundle should be executed in the application’s directory, and then come back to the original directory, in order not to disrupt anything that may be executed afterwards.

Publishing the application

To publish the application on OpenShift, just issue the git push command as below:

1
$ git push openshift master

Import database from Heroku

Importing and exporting PostgresSQL databases on Heroku is well documented here. Firstly, we need to add pgbackup addon to our Heroku app:

1
$ heroku addons:add pgbackups

To export the data from Heroku PostgresSQL database, create a new backup and use any number of download tools, such as curl or wget, to store the backup locally.

1
2
$ heroku pgbackups:capture
$ curl -o latest.dump `heroku pgbackups:url`

Restore database on OpenShift

To restore the database on OpenShift, we need to know the value of OPENSHIFT_POSTGRESQL_DB_USERNAME environment variable. Issue following commands to get this information:

1
2
3
$ rhc ssh myapp
$ env| grep OPENSHIFT_POSTGRESQL_DB_USERNAME
$ exit

Take a note of the output and start port forwarding as below:

1
$ rhc port-forward myapp

It will give output similar to following:

1
2
3
4
5
6
7
8
9
10
11
12
Checking available ports ... done
Forwarding ports ...

To connect to a service running on OpenShift, use the Local address

Service    Local                OpenShift
---------- --------------- ---- ----------------
httpd      127.0.0.1:8080   =>  x.x.x.x:8080
postgresql 127.0.0.1:5432   =>  x.x.x.x:5432
ruby       127.0.0.1:32036  =>  x.x.x.x:32036

Press CTRL-C to terminate port forwarding

Now issue following commang to restore the database:

1
$ pg_restore –verbose –clean –no-acl –no-owner -h localhost -U OPENSHIFT_POSTGRESQL_DB_USERNAME -d myapp latest.dump

Replace OPENSHIFT_POSTGRESQL_DB_USERNAME with the output from command at the start of this section.

And that’s it. Now visit the application and make sure everything is working as expected.

Epilogue

Heroku is a great platform for developing and deploying Rails application. I started looking for alternatives of Heroku because once I enabled rails_admin gem in my application, Heroku was not able to serve the requests. I started getting intermittent application error. Once I migrated to OpenShift, these errors went away.