Featured image of post Deploying a Sinatra API on Azure App Service

Deploying a Sinatra API on Azure App Service

How to deploy a Sinatra service to Azure

I was recently exposed to Sinatra as an alternative to Rails. The simplicity of it has got me hooked. As a primarily .NET/NodeJS developer, being able to build out and deploy minimal surface APIs is something I’ve missed while working in Rails. Naturally, I needed to connect to my Microsoft background by deploying Sinatra to Azure. While there is loads of information on deploying Rails to Azure, there are small tweaks that need to be done to deploy a Sinatra application.

Deploying a Sinatra app on Azure is a simple process that consists of uploading your application code to an Azure web app and configuring it to run on the Azure platform. To begin, you will need an Azure account, a local installation of Ruby, Git and the Azure CLI. Using the Azure CLI, you can create a new web app and use Git to upload your application code to it. Once the code is uploaded, you’ll need to configure the app’s settings, such as environment variables and runtime, to ensure it runs correctly on Azure. We’ll go over these steps below to deploy a simple API to the platform.

Creating the sample Sinatra API

Sinatra is an awesome, low friction, quick to get running Ruby framework for running APIs. If you’re here, you probably already know that but if you’re new to Sinatra, be sure to check out their docs.

We’ll begin by creating the directory for our app and creating all of the necessary files. Open a terminal and run the following commands

1
2
3
4
mkdir sinatra-sample
cd sinatra-sample
mkdir config
touch Gemfile config.ru app.rb config/puma.rb

Open the Gemfile and paste the following code

1
2
3
source 'https://rubygems.org'
gem 'sinatra'
gem 'puma'

Open the config.ru and paste the following code

1
2
require './app'
run Sinatra::Application

Open the app.rb and paste the following code

1
2
3
4
5
require 'sinatra'

get '/' do
  'Hello world!'
end

Open the config/puma.rb and paste the following code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# Puma can serve each request in a thread from an internal thread pool.
# The `threads` method setting takes two numbers: a minimum and maximum.
# Any libraries that use thread pools should be configured to match
# the maximum value specified for Puma. Default is set to 5 threads for minimum
# and maximum; this matches the default thread size of Active Record.
#
threads_count = ENV.fetch("MAX_THREADS") { 5 }
threads threads_count, threads_count

# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
#
port        ENV.fetch("PORT") { 3000 }

# Specifies the `environment` that Puma will run in.
#
environment ENV.fetch("APP_ENV") { "development" }

# Specifies the number of `workers` to boot in clustered mode.
# Workers are forked webserver processes. If using threads and workers together
# the concurrency of the application would be max `threads` * `workers`.
# Workers do not work on JRuby or Windows (both of which do not support
# processes).
#
# workers ENV.fetch("WEB_CONCURRENCY") { 2 }

# Use the `preload_app!` method when specifying a `workers` number.
# This directive tells Puma to first boot the application and load code
# before forking the application. This takes advantage of Copy On Write
# process behavior so workers use less memory.
#
# preload_app!

# Allow puma to be restarted by `rails restart` command.
plugin :tmp_restart

That’s it! That’s all we need to get running. Run the commands below and navigate to localhost:3000 to see your app

1
2
bundle install
bundle exec puma

Initializing the repository

We’re going to be using the Azure Git Deploy method so we need to make our directory a Git repository. We will create a main branch as a default and later on, we’ll add an Azure branch to trigger deploys. Alternatively, you could set up your favorite CI/CD tool such as GitHub Actions.

Run the following commands to create your repository and commit all of the files we just created to it

1
2
3
4
git init
git branch -b main
git add .
git commit -am "initial commit"

Setting up the Azure resources

We’re almost there! Just a few more commands to run now! In the following steps, we’ll create a resource group, an app service plan, and an app service. Note the app service name needs to be unique in Azure so you will likely need to change the names we use

First we need to login to the Azure CLI and create a deployment user

1
2
az login
az webapp deployment user set --user-name <username> --password <password>

Next we need to create a resource group to deploy our app service plan. We’ll make this one in US West but you can choose a region closer to you

1
az group create --name sinatra-blog --location "West US"

We’ll now create a Linux app service plan to host our web app. As a side bar, at KTFA we have been using Linux web apps on Azure for quite some time. The tooling is amazing and the services are super reliable. At this point, unless you absolutely must, it seems like a waste of money to pay for a Windows plan.

1
az appservice plan create --name sinatra-blog --resource-group sinatra-blog --sku FREE --is-linux

Now we’ll create our web app which will also give us our Azure git repository

1
az webapp create --resource-group sinatra-blog --plan sinatra-blog --name sinatra-blog-app --runtime 'RUBY|2.7' --deployment-local-git

NOTE: The URL of the Git remote is shown in the deploymentLocalGitUrl property, with the format https://user@app-name.scm.azurewebsites.net/app-name.git. Save this URL as you need it later.

Now we need to add a couple app settings. The first setting will tell Azure which branch to watch in order to trigger deployments. The second will be setting the startup command we need for Sinatra. By default, Azure tries to start it as a Rails app so this will fix that

1
2
az webapp config appsettings set --name sinatra-blog-app --resource-group sinatra-blog --settings DEPLOYMENT_BRANCH='main'
az webapp config appsettings set --name sinatra-blog-app --resource-group sinatra-blog --settings APP_COMMAND_LINE='bundle exec puma config.ru -C config/puma.rb'

Setting up the Azure git branch

Phew, we did it. Now all that is left is to deploy this thing. This is just a matter of a couple git commands

1
2
git remote add azure <deploymentLocalGitUrl-from-create-step>
git push azure main

You’ll see a lot of out put from the previous commands. Once it is all done running navigate to .azurewebsites.net (in our case sinatra-blog-app.azurewebsites.net/). It will take a bit of time to spin up since we used the free tier. You may even see an Error 503 while it is being set up. Once it does load, you should see your new app in the browser!

Our Sinatra App

Congrats you did it! Go forth and build!

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy