2015-09-27



Introduction
Rails is an open source web application framework written in Ruby. It follows the Convention over Configuration philosophy by making assumptions that there is the 'best' way of doing things. This allows you to write less code while accomplishing more without having you go through endless config files.
Nginx is a high performance HTTP server, reverse proxy, and a load balancer known for its focus on concurrency, stability, scalability, and low memory consumption. Like Nginx, Puma is another extremely fast and concurrent web server with a very small memory footprint but built for Ruby web applications.
Capistrano is a remote server automation tool focusing mainly on Ruby web apps. It's used to reliably deploy web apps to any number of remote machines by scripting arbitrary workflows over SSH and automate common tasks such as asset pre-compilation and restarting the Rails server.
In this tutorial we'll install Ruby and Nginx on a DigitalOcean Ubuntu Droplet and configure Puma and Capistrano in our web app. Nginx will be used to capture client requests and pass them over to the Puma web server running Rails. We'll use Capistrano to automate common deployment tasks, so every time we have to deploy a new version of our Rails app to the server, we can do that with a few simple commands.

Prerequisites
To follow this tutorial, you must have the following:

Ubuntu 14.04 x64 Droplet

A non-root user named deploy with sudo privileges (Initial Server Setup with Ubuntu 14.04 explains how to set this up.)

Working Rails app hosted in a remote git repository that's ready to be deployed

Optionally, for heightened security, you can disable root login via SSH and change the SSH port number as described in Initial Server Setup with Ubuntu 14.04.

Warning: After disabling root login, make sure you can SSH to your Droplet as the deploy user and use sudo for this user before closing the root SSH session you opened to make these changes.
All the commands in this tutorial should be run as the deploy user. If root access is required for the command, it will be preceded by sudo.

Step 1 — Installing Nginx
Once the VPS is secure, we can start installing packages. Update the package index files:

Then, install Nginx:

Step 2 — Installing Databases
Install the database that you'll be using in your Rails app. Since there are lots of databases to choose from, we won't cover them in this guide. You can see instructions for major ones here:

MySQL

PostgreSQL

MongoDB

Also be sure to check out:

How To Use MySQL with Your Ruby on Rails Application on Ubuntu 14.04

How To Use PostgreSQL with Your Ruby on Rails Application on Ubuntu 14.04

Step 3 — Installing RVM and Ruby
We won't be installing Ruby directly. Instead, we'll use a Ruby Version Manager. There are lots of them to choose from (rbenv, chruby, etc.), but we'll use RVM for this tutorial. RVM allows you to easily install and manage multiple rubies on the same system and use the correct one according to your app. This makes life much easier when you have to upgrade your Rails app to use a newer ruby.
Before installing RVM, you need to import the RVM GPG Key:

Then install RVM to manage our Rubies:

This command uses curl to download the RVM Installation script from https://get.rvm.io. The -sSL option is composed of three flags:

-s tells curl to download the file in 'silent mode'

-S tells curl to show an error message if it fails

-L tells curl to follow all HTTP redirects while retrieving the installation script

Once downloaded, the script is piped to bash. The -s option passes stable as an argument to the RVM Installation script to download and install the stable release of RVM.

Note: If the second command fails with the message "GPG signature verification failed", that means the GPG Key has changed, simply copy the command from the error output and run it to download the signatures. Then run the curl command for the RVM Installation.
We need to load the RVM script (as a function) so we can start using it. We then need to run the requirements command to automatically install required dependencies and files for RVM and Ruby to function properly:

We can now install the Ruby of our choice. We'll be installing the latest Ruby 2.2.1 (at the time of writing) as our default Ruby:

Step 4 — Installing Rails and Bundler
Once Ruby is set up, we can start installing Rubygems. We'll start by installing the Rails gem that will allow your Rails application to run, and then we'll install bundler which can read your app's Gemfile and automatically install all required gems.
To install Rails and Bundler:

Three flags were used:

-V (Verbose Output): Prints detailed information about Gem installation

--no-ri - (Skips Ri Documentation): Doesn't install Ri Docs, saving space and making installation fast

--no-rdoc - (Skips RDocs): Doesn't install RDocs, saving space and speeding up installation

Note: You can also install a specific version of Rails according to your requirements by using the -v flag:

Step 5 — Setting up SSH Keys
Since we want to set up smooth deployments, we'll be using SSH Keys for authorization. First shake hands with GitHub, Bitbucket, or any other Git Remote where the codebase for your Rails app is hosted:

Don't worry if you get a Permission denied (publickey) message. Now, generate a SSH key (a Public/Private Key Pair) for your server:

Add the newly created public key (~/.ssh/id_rsa.pub) to your repository's deployment keys:

Instructions for Github

Instructions for Bitbucket

If all the steps were completed correctly, you should now be able to clone your git repository (over the SSH Protocol, not HTTP) without entering your password:

If you need a sample app for testing, you can fork the following test app specifically created for this tutorial: Sample Rails App on GitHub

The git clone command will create a directory with the same name as your app. For example, a directory named testapp_rails will be created.
We are cloning only to check if our deployment keys are working, we don't need to clone or pull our repository every time we push new changes. We'll let Capistrano handle all that for us. You can now delete this cloned directory if you want to.

Open a terminal on your local machine. If you don't have a SSH Key for your local computer, create one for it as well. In your local terminal session:

Add your local SSH Key to your Droplet's Authorized Keys file (remember to replace the port number with your customized port number):

Step 6 — Adding Deployment Configurations in the Rails App
On your local machine, create configuration files for Nginx and Capistrano in your Rails application. Start by adding these lines to the Gemfile in the Rails App:

Gemfile

Use bundler to install the gems you just specified in your Gemfile. Enter the following command to bundle your Rails app:

After bundling, run the following command to configure Capistrano:

This will create:

Capfile in the root directory of your Rails app

deploy.rb file in the config directory

deploy directory in the config directory

Replace the contents of your Capfile with the following:

Capfile

This Capfile loads some pre-defined tasks in to your Capistrano configuration files to make your deployments hassle-free, such as automatically:

Selecting the correct Ruby

Pre-compiling Assets

Cloning your Git repository to the correct location

Installing new dependencies when your Gemfile has changed

Replace the contents of config/deploy.rb with the following, updating fields marked in red with your app and Droplet parameters:

config/deploy.rb

This deploy.rb file contains some sane defaults that work out-of-the-box to help you manage your app releases and automatically perform some tasks when you make a deployment:

Uses production as the default environment for your Rails app

Automatically manages multiple releases of your app

Uses optimized SSH options

Checks if your git remotes are up to date

Manages your app's logs

Preloads the app in memory when managing Puma workers

Starts (or restarts) the Puma server after finishing a deployment

Opens a socket to the Puma server at a specific location in your release

You can change all options depending on your requirements. Now, Nginx needs to be configured. Create config/nginx.conf in your Rails project directory, and add the following to it (again, replacing with your parameters):

config/nginx.conf

Like the previous file, this nginx.conf contains defaults that work out-of-the-box with the configurations in your deploy.rb file. This listens for traffic on port 80 and passes on the request to your Puma socket, writes nginx logs to the 'current' release of your app, compresses all assets and caches them in the browser with maximum expiry, serves the HTML pages in the public folder as static files, and sets default maximum Client Body Size and Request Timeout values.

Step 7 — Deploying your Rails Application
If you are using your own Rails app, commit the changes you just made, and push them to remote from your Local Machine:

Note: If this is the first time using GitHub from this system, you might have to issue the following commands with your GitHub username and email address:

Again, from your local machine, make your first deployment:

This will push your Rails app to the Droplet, install all required gems for your app, and start the Puma web server. This may take anywhere between 5-15 minutes depending on the number of Gems your app uses. You will see debug messages as this process occurs.
If everything goes smoothly, we're now ready to connect your Puma web server to the Nginx reverse proxy.
On the Droplet, Symlink the nginx.conf to the sites-enabled directory:

Restart the Nginx service:

You should now be able to point your web browser to your server IP and see your Rails app in action!

Normal Deployments
Whenever you make changes to your app and want to deploy a new release to the server, commit the changes, push to your git remote like usual, and run the deploy command:

Note: If you make changes to your config/nginx.conf file, you'll have to reload or restart your Nginx service on the server after deploying your app:

Conclusion

Okay, so by now you would be running a Rails app on your Droplet with Puma as your Web Server as well as Nginx and Capistrano configured with basic settings. You should now take a look at other docs that can help you optimize your configurations to get the maximum out of your Rails application:

Show more