Ruby + Sinatra + Azure
Following excellent work done by Thomas Conte and Richard Conway, I thought it would be interesting to get a Ruby application running in Azure’s PaaS – Cloud Services (i.e. a WorkerRole) in a really simple way.
I have created a sample on GitHub, this article walks through the steps I took to set it up.
Create a Visual Studio project
Start by creating a Cloud Project in Visual Studio, and add a Worker Role. This will basically bootstrap the Ruby application.
In the Worker Role project we’ll add the files we need deployed to the Azure machine.
To install Ruby, I used the x64 Windows Installer from RubyInstaller.com.
Download the installer and add it to the Worker Role project. On properties of this file, select ‘Copy to output directory’ -> ‘Copy if newer’ to ensure it gets included in the package.
Add a script file ‘install.cmd’ to the project, ensure this is encoded as US-ASCII (anything but the default encoding for a text file in Visual Studio!) set the properties to ‘Copy if newer’.
The file should look like this:
rubyinstaller-2.0.0-p0-x64.exe /silent D:\Ruby200-x64\bin\gem.bat install sinatra --no-ri --no-rdoc
This will install ruby and the Sinatra gem.
Add a ‘main.rb’ file to the Worker Role project, set it to ‘copy if newer’. The file should look like this:
require 'sinatra' set :environment, :production set :port, 8080 get '/' do "Hello World!" end
I had trouble getting Sinatra to work on the default port, but 8080 seems to work fine.
Add a script file called ‘start.cmd’ to the Worker Role project, and as before, set it to ‘copy if newer’. The file should contain a line like this, and which will start the Sinatra process:
Configuring the Cloud Project
The final piece is to wire up the script files, and open the correct ports in the firewall. This is done by modifying the ServiceDefinition.csdef file to look like this:
<?xml version="1.0" encoding="utf-8"?> <ServiceDefinition name="RubyOnAzure" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition" schemaVersion="2012-10.1.8"> <WorkerRole name="WorkerRole1" vmsize="Small"> <Startup> <Task commandLine="install.cmd" executionContext="elevated" taskType="simple"></Task> <Task commandLine="start.cmd" executionContext="elevated" taskType="background"></Task> </Startup> <Imports> <Import moduleName="Diagnostics" /> </Imports> <Endpoints> <InputEndpoint name="Endpoint1" protocol="tcp" port="80" localPort="8080" /> </Endpoints> </WorkerRole> </ServiceDefinition>
I have put the example project on GitHub.