Skip to main content

How to deploy Sinatra App with Puma and NginX (manually - no Capistrano)

2 min read

Sinatra is a great classy tool for small but dynamic sites. Actually I'll use Sinatra or any other micro framework even with static sites just for templating support and routes. I wouldn't like to repead headers and footers with every single HTML file!

Building even static websites will be fun with sinatra! But deploying might not be fun for everyone. Specially small websites, where incorporating Capistrano might seem a little hectic. (Though I would highly recommend Capistrano with any size of app, it makes updates so easy. Wait for the next post.) So, Today I'll show you how to deploy a Sinatra App manually with Puma and Nginx.

First lets build our sample app. Before that, install Sinatra and Puma as usual.

gem install sinatra
gem install puma

Create a directory for your app, maybe named my_app. Now the App:

require 'sinatra'

class App < Sinatra::Base
  get '/' do
    'Hello Frank!'
  end
end

Nothing fancy. Just a root route to prove our app is working. Save this in app.rb named file in my_app.

Now we need a rackup file. Save below content in a config.ru file.

require_relative 'app'

run App

Finally our Puma config file:

root = "#{Dir.getwd}"

activate_control_app "tcp://127.0.0.1:9293"
bind "unix://#{root}/tmp/puma.sock"
pidfile "#{root}/tmp/pids/puma.pid"
rackup "#{root}/config.ru"
state_path "#{root}/tmp/pids/puma.state"
daemonize true

Save it in puma.rb file. We need some supporting directories.

mkdir -p tmp/pids public

At this poing, your app should be working. You can run, stop the app with pumactl

pumactl -F puma.rb start # Start the app
pumactl -F puma.rb restart # Restart the app
pumactl -F puma.rb stop # Stop the app

But we still need to integrate it with NginX to make it live. Here is the NginX vhost config:

upstream sinatra {
    server unix:/PATH/TO/YOUR/APP/tmp/puma.sock;
}

server {
    listen 80;
    root /PATH/TO/YOUR/APP/public;
    server_name YOUR_DOMIAN.COM;

    location / {
        try_files $uri $uri/index.html @puma;
    }

    location @puma {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_pass http://sinatra;
  }

}

Obviously replace PATH/TO/YOUR/APP with correct path and YOUR_DOMIAN.COM with your domain. This code will preferabbly go into a file inside /etc/nginx/sites-enabled.

Restart NginX. Visit your URL. Your Sinatra app is live. :)