Production Ready Deployment for RoR – Puma, Nginx

Production Ready Deployment for RoR – Puma, Nginx

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.

Prerequisites

  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’
End

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
Capified

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, ‘git@bitbucket.org:bitcot/help-rails.git’
set :deploy_to, ‘/home/ubuntu/www/help’
set :rvm_ruby_version, ‘2.5.0@help’

Open DB.yml
vi config/database.yml
production:
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 http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-pgdg main” >> /etc/apt/sources.list.d/pgdg.list’

wget -q https://www.postgresql.org/media/keys/ACCC4CF8.asc -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 :

psql

For Mac:

psql postgres

To exit shell

\q

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
ALTER USER  WITH PASSWORD ”;

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
<Imah>

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

Author: Raj Sanghvi

Raj Sanghvi is a technologist, innovator and founder/CEO of BitCot, a full service award-winning application development company. With BitCot, Sanghvi has helped over 100 clients develop mobile apps & SaaS platforms, making them affordable and successful. Visit Raj Sanghvi on LinkedIn and follow him on Twitter, @BitCot.View Full Bio

Free project quote

Fill out the enquiry form and we'll get
back to you as soon as possible.
Contact Us: 858-683-3692
Dave S

Dave S

Co-Founder- StompSessions

Quote

I have Known BitCot for 4 years and have been impressed with the diversity and quality of BitCot’s work. With that solid foundation it was really easy to select BitCot as our development partner. Quote

Show Buttons
Hide Buttons