Setup Ruby on Rails with Nginx + Passenger on Ubuntu 16.04

In this article, I want to explain how to setup Ruby on Rails application on Ubuntu 16.04 server via Nginx and Passenger. And how to setup deploy via Capistrano.

  1. Create deploy user
  2. Install RVM and Ruby
  3. Install Passenger packages
  4. Enable the Passenger Nginx module
  5. Setup Nginx server
  6. Install PostgreSQL
  7. Setup deploy with Capistrano

Create deploy user

If you are signed in as the root user, you can create a new user at any time by typing:

adduser deploy

Add your SSH key to /home/deploy/.ssh/authorized_keys and set permissions


Now we can log in as deploy


Install RVM and Ruby

\curl -sSL | bash -s -- --autolibs=read-fail

logout and login again

rvm install 2.3

Install ruby dependencies (as root)

apt-get install g++ gcc make libc6-dev libreadline6-dev zlib1g-dev libssl-dev 
libyaml-dev libsqlite3-dev sqlite3 autoconf libgmp-dev libgdbm-dev libncurses5-dev 
automake libtool bison pkg-config libffi-dev
apt-get install git libpq-dev

More info you can find on official site

Install Passenger packages

Login as root and use these commands will install Passenger

sudo apt-get install -y dirmngr gnupg
sudo apt-key adv --keyserver hkp:// --recv-keys 561F9B9CAC40B2F7
sudo apt-get install -y apt-transport-https ca-certificates

Change trusty version to your distributive version, if it has another version

sudo sh -c 'echo deb trusty main > /etc/apt/sources.list.d/passenger.list'
sudo apt-get update

Now you can install Passenger + Nginx

sudo apt-get install -y nginx-extras passenger

Enable the Passenger Nginx module

Edit /etc/nginx/nginx.conf and uncomment the line include /etc/nginx/passenger.conf;

For example, you may see this:

# include /etc/nginx/passenger.conf;

Remove the '#' characters, like this:

include /etc/nginx/passenger.conf;

After installation, please validate the install by running the next command:

sudo /usr/bin/passenger-config validate-install

And check Nginx configuration

nginx -t

If you are successfully finished these steps, you can restart Nginx:

sudo service nginx restart

More info you can find on this article

Setup Nginx server

Login as root, going to the Nginx folder

cd /etc/nginx/conf.d/

Make config file


And copy the next configuration

server {
  listen 80;
  listen [::]:80;
  return 301$request_uri;

server {
  listen 80;
  listen [::]:80;

  root /var/www/example/current/public;
  passenger_enabled on;

  index index.html index.htm index.nginx-debian.html;

  client_max_body_size 100M;

Check Nginx configuration nginx -t and restart the server if all right.

Install PostgreSQL

sudo apt-get update
sudo apt-get install postgresql postgresql-contrib

Login to PostgreSQL by the default user

sudo -i -u postgres

Create new database user with the same name of deploy user

CREATE USER deploy WITH password 'password';

Currently, we just have the postgres role configured within the database. We can create new roles from the command line with the createrole command.

The --interactive a flag will prompt you for the necessary values. If you are logged in as the postgres account, you can create a new user by typing:

createuser --interactive

More info you can find on this article

Setup deploy with Capistrano

Open your Gemfile and next gems to the development section

group :development do
  gem 'capistrano', '~> 3.0', require: false
  gem 'capistrano-rails', require: false
  gem 'capistrano-rvm', require: false
  gem 'capistrano-passenger', require: false
  gem 'capistrano-faster-assets', require: false

and run bundle install after gem installation run cap install for setup deploy.

This command make the next files

create config/deploy.rb
create config/deploy/staging.rb
create config/deploy/production.rb
create Capfile

In the first time you need to update Capfile for enabling plugins. For example, your file should be:

# Load DSL and set up stages
require 'capistrano/setup'

# Include default deployment tasks
require 'capistrano/deploy'

require 'capistrano/scm/git'
install_plugin Capistrano::SCM::Git

require 'capistrano/rvm'
require 'capistrano/bundler'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
require 'capistrano/passenger'
require 'capistrano/faster_assets'

# Load custom tasks from `lib/capistrano/tasks` if you have any defined
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }

Next, you should configure the base deploy file (config/deploy.rb)

# config valid only for current version of Capistrano
lock '3.10.1'

require 'dotenv'

set :application, 'example'
set :repo_url, ''

set :branch, `git rev-parse --abbrev-ref HEAD`.chomp
set :deploy_to, proc { "/var/www/#{fetch :application}" }
set :deploy_via, :remote_cache
set :format, :airbrussh

set :log_level, :info
set :pty, false

append :linked_files, 'config/database.yml', '.env'
append :linked_dirs, 'log', 'tmp/pids', 'tmp/cache', 'tmp/sockets'

set :ssh_options, forward_agent: true

set :rvm_type, :user
set :rvm_ruby_version, '2.3.4'

set :keep_releases, 5

And now add setup config for environment

set :rails_env, 'production'
server '', user: 'deploy', roles: %w[app db web]

That's all, you can deploy the project to the server. For this need run cap production deploy

Before deploy, you need to create linked config files /var/www/example/shared/config/database.yml and /var/www/example/shared/.env