Skip to main content

Production Ready Deployment for RoR – Puma, Nginx

By May 22, 2018December 11th, 2023Startups
ror puma nginx hero

This tutorial will help you deploy the Rails 5 application for production environment with PostgreSQL on RDS as the database, using Puma and Nginx on Ubuntu 16.04.


  1. AWS EC2 Ubuntu instance
  2. Postgresql RDS Instance
  3. Rubymine ( IDE )
  4. Ruby and Rails installed on your workstation

By this time you would have your rails 5 app already ready and working fine on your local env.

To deploy your rails 5 app we will use popular deployment tool Capistrano

Starting Deployment Process:

Rails 5 by default has puma as default web server , next thing will be adding Capistrano to your project’s Gemfile

Add following gems in gemfile
group :development do
gem ‘capistrano’, ‘~> 3.8.2’
gem ‘capistrano-rvm’
gem ‘capistrano-rails’, ‘~> 1.1.0’
gem ‘capistrano3-puma’

Once this is done, Next task is to bundle install. This can be done using the command

bundle install

After installing next big task is to execute capistrano.

This can be done by Cap install command

This will create few files

mkdir -p config/deploy
create config/deploy.rb
create config/deploy/staging.rb
create config/deploy/production.rb
mkdir -p lib/capistrano/tasks
create Capfile

Open deploy.rb

server ‘IP address’, roles: %w(app db), user: ‘ubuntu’

set :assets_roles, [:app] set :rails_env, production
set :migrate_env, production

Open Deploy.rb

set :repo_url, ‘’
set :deploy_to, ‘/home/ubuntu/www/help’
set :rvm_ruby_version, ‘2.5.0@help’

Open DB.yml
vi config/database.yml
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch(“RAILS_MAX_THREADS”) { 5 } %>
database: name_of_the_db
user: username
password: password
host:  localhost
port: 5432

Open ec2 instance

Install postgreql

Step 1: Open terminal and install postgres

sudo sh -c ‘echo “deb `lsb_release -cs`-pgdg main” >> /etc/apt/sources.list.d/pgdg.list’

wget -q -O – | sudo apt-key add –

sudo apt-get update

sudo apt-get install postgresql postgresql-contrib

Step 2: Default Postgres role is now created

sudo -i -u postgres #if your on mac it will be ur system name

if you are a normal users it will prompt for a password else it will take to postgres shell

Step 3: Command to interact

For ubuntu :


For Mac:

psql postgres

To exit shell


Step 4: Create a New user

createuser –interactive

Enter name of role to add: nimbus_user

#this should be name of the username mentioned in ur rails app ( database.yml)

Shall the new role be a superuser? (y/n) y

Note: Follow 4.1 at end, proceed for step 5

Step 4.1: Adding password to user

sudo -i -u postgres
psql postgres

Step 5: Create a db

createdb nimbus_staging

#this should be name of the db name mentioned in ur rails app ( database.yml)

and then exit the app

Note: sudo updatedb – once db is created

Step 6: changing the postgres conf to accept password and not peer

Open pg_hba.conf and at the bottom, change local, IP4v to trust from trust

Run: Locate pg_hba.conf

$ sudo vim /etc/postgresql/9.6/main/pg_hba.conf

at the bottom, change local, IP4v to trust from trust.

Step 7: Edit  postgresql.conf to hear for connections

Note: $ locate postgresql.conf

$ sudo vim /etc/postgresql/9.6/main/postgresql.conf

Look for this line:

#listen_addresses = ‘localhost’

And change it to:

listen_addresses = ‘*’
remove comment from line

We’re telling PostgreSQL to list for connections from any source, not only locally.

Step 8: Restart Postgres

sudo service postgresql restart

Install and Configure Nginx

Install Nginx using apt-get:

sudo apt-get install nginx

To validate this, open IP Address on your browser and it will show nginx welcome screen

Now open the default server block with a text editor:

sudo vi /etc/nginx/sites-available/default

Replace the contents of the file with the following code block. Be sure to replace the the highlighted parts with the appropriate username and application name (two locations):

upstream app {
# Path to Puma SOCK file, as defined previously
server unix:/home/deploy/appname/shared/sockets/puma.sock fail_timeout=0;

server {
listen 80;
server_name ipaddress;

root /home/deploy/appname/public;

try_files $uri/index.html $uri @app;

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

error_page 500 502 503 504 /500.html;
client_max_body_size 4G;
keepalive_timeout 10;

Save and exit.

Restart Nginx to put the changes into effect:

sudo service nginx restart

You should see the same page that you saw the first time you tested your application, but now it’s being served through Nginx and Puma.

Deploy code

Cap production deploy

Raj Sanghvi

Raj Sanghvi is a technologist and founder of BitCot, a full-service award-winning software development company. With over 15 years of innovative coding experience creating complex technology solutions for businesses like IBM, Sony, Nissan, Micron, Dicks Sporting Goods, HDSupply, Bombardier and more, Sanghvi helps build for both major brands and entrepreneurs to launch their own technologies platforms. Visit Raj Sanghvi on LinkedIn and follow him on Twitter. View Full Bio