Sinatra Starter for Predix: Ruby App with PostgreSQL and Redis
The technical requirements for the Internet of Things (IoT) server applications can substantially differ from the ones applied to the Internet of Humans. First of all, the need for any visual interfaces is completely eliminated.
These step-by-step instructions are intended to guide you through the process of starting a basic Ruby/Sinatra application server on Predix, GE’s IoT platform for the Industrial Internet. From the post, you can learn how to deploy the application to Predix, as well as configure the PostgreSQL database and Redis.
Sinatra is a simple Ruby framework that has the flexibility to focus on the main task of exchanging information between the server and clients.
Since we are going to concentrate on Predix deployment rather than on preparing a Sinatra application, I’ll use Hazel to streamline the process:
gem install hazel hazel predix_sinatra_starter -d postgres --redis --rvm --git
Executing these commands generates a proper Sinatra application skeleton prepared to run PostgreSQL through Sequel and with Redis bindings.
You might need to temporarily comment out the
Sequel.connect attempts in
config/initializers/database.rb until you configure the connection. The command below will start the application for you locally to check that it works:
To follow along, you can use our sample application.
Deploying the application to Predix
To get started, follow the installation instructions for the Cloud Foundry CLI binaries.
curl -L "https://cli.run.pivotal.io/stable?release=linux64-binary&source=github" | tar -zx ./cf --version ./cf --help
cf login -a https://api.system.aws-usw02-pr.ice.predix.io command to enter your authentication data.
Cloud Foundry needs the
manifest.yml file for your application, which we’re going to create now in the application root:
applications: - name: sinatra-app buildpack: https://github.com/cloudfoundry/ruby-buildpack memory: 64M stack: cflinuxfs2
Because we work with the Ruby Cloud Foundry buildpack, there are a couple of things we need to do:
Declare a Ruby version in your
Gemfileby adding the following line:
Procfilestarting your application to the root. Ensure it is a valid YAML hash.
web: rackup config.ru -p $PORT
Reading from the global
$PORTvariable is crucial here because Cloud Foundry-based Predix assigns you the port to run on and expects you to use it.
- Be sure to add the
.cfignorefile to the root of the application. It should list all files and folders in your project directory tree you don’t want to be uploaded to production.
cf push command will upload, bundle, and run our simple Sinatra application.
Configuring the PostgreSQL database
Create a local Postgres DB for development:
Rakefile with the
namespace :db do task :environment do require 'sequel' ENV['RACK_ENV'] ||= 'development' end end
If you used Hazel to generate your application, rename its default database configuration file
config/db.yml into a standard
config/database.yml file. This is the file the Ruby buildpack will replace with an auto-generated one in production. Make sure the file contains your local database’s address:
Note that the simplest database setup might result in Postgres refusing the connection due to no password being supplied. My usual local development databases run in a not-so-safe mode of allowing any local connections, but you can tweak this step of database setup to use password protection.
Let’s create a migration that will demonstrate we have a proper connection between the application and the database.
Add an indicator that we have data access from Sinatra to
<%= DB[:items].map(:name) %>
Create a Postgres service as described in Predix Documentation and associate it with your application.
cf create-service postgres shared-nr sinatra-postgres-test cf bind-service sinatra-app sinatra-postgres-test cf restage sinatra-app
As I’ve already mentioned, the Ruby buildpack writes a new
database.yml file. However, the file is ERB enhanced, so it will fail our current application’s database initialization. To avoid that, Sinatra can take a note from Rails, which runs this file through ERB when loading it, to allow various dynamic options.
config/initializers/database.rb file, replace
settings = YAML::load_file("config/database.yml") with:
require ‘erb’ settings = YAML.load(ERB.new(File.read('config/database.yml')).result)
Finally, update the
Procfile for it to try running the migrations each time we deploy.
To limit the number of times the migration gets triggered, you can add a classic Cloud Foundry Rake task limiting the Rake execution to only the first instance (when in the batch).
namespace :cf do desc 'Only run on the first application instance' task :on_first_instance do instance_index = JSON.parse(ENV["VCAP_APPLICATION"])["instance_index"] rescue nil exit(0) unless instance_index == 0 end end
web: bundle exec rake cf:on_first_instance db:migrate && rackup config.ru -p $PORT
Push the new application version:
Setting up Redis requires following pretty much the same steps as configuring PostgreSQL.
cf create-service redis-1 shared-vm sinatra-redis-test cf bind-service sinatra-app sinatra-redis-test
Modify the Redis initializer to read the configuration from an environment variable.
if ENV['VCAP_SERVICES'] require 'json' credentials = JSON.parse(ENV['VCAP_SERVICES'])["redis-1"].first["credentials"] REDIS = Redis.new(credentials) end
You can also see this and other production variables by running the following command:
cf env sinatra-app
Deploy the new version:
- Get Started with Predix: Deploying a Rails App and Binding Services
- Using Predix Mobile Services for a Cross-platform App
- Deploying an ASP.NET Application to GE Predix
For the next parts of this series, subscribe to our blog or follow @altoros.