Skip to content

Deploying a Rails App The Easy Way

Posted on:July 28, 2015

Introduction

You’ve written the app, you’ve deployed it on Heroku, and now it’s time to deploy your app for production on a real server. There are a few advantages of a server (dedicated or VPS) over something like Heroku. It mainly boils down to:

Signing Up

First, we need to sign up for DigitalOcean: a VPS service renowned for the speed and simplicity of their VPS instance (known as Droplets) spawning, as well as great features like backups, IPV6, and SSDs in all VPS instances. Sign up for DigitalOcean here!

Creating a Droplet

Let’s create a droplet. I’ve included a list of the specifications for the droplet I’m using, but you can see a screenshot of the settings here.

Logging In

The new droplet’s information will be emailed to you. It will include the IP and the server’s root password.

Let’s start by logging in to the droplet via SSH:

$ ssh [email protected]

  [email protected]'s password: 
  Changing password for root.
  (current) UNIX password: 
  New password: 
  Retype new password: 

[root@ruby-on-rails ~]#                     

When prompted that the authenticity of the host can’t be established, type yes. On first login, you will be prompted to change your password. Make sure you write it down! It is possible to change it later through DigitalOcean’s dashboard, but it is much easier to simply not forget in the first place!

Installation

Now that we’re logged in, let’s start with the installation of some basic tools we’ll need. I’m not going to go into much detail about these packages, as there are tons of resources on them.

We’ll also be using nginx as our server. Nginx is blazingly fast with very low memory usage. At the same time, it is easy to install and configure.

General Development Tools

We will be installing most of what we need using yum, the package manager included with CentOS. When yum asks Is this ok [y/d/N]:, enter y.

# yum install epel-release curl-devel httpd-devel
# yum groupinstall 'Development Tools' 

nginx

To install nginx, we will be using nginx’s Official CentOS package.

# nano /etc/yum.repos.d/nginx.repo

And enter the following:

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1

Then, we can use yum install nginx which will install from nginx directly. This method is preferred over installation by any other method, including from source (unless necessary, as some features can only be enabled through installing from source).

Great! Nginx is installed. Let’s see if we can talk to it. Start nginx and navigate to your IP address (mine is 104.131.56.255) in the browser. You should see nginx’s welcome page:

# nginx

There is a bit more configuration for us to do, but we’ll come back to nginx later.

RVM

Though many distributions of linux come with Ruby installed, we’re going to do it the right way. This involves using RVM, the Ruby Version Manager.

To install RVM:

# gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
# \curl -sSL https://get.rvm.io | bash -s stable

Then, following the instructions given to us, we will add our user to the rvm group (do this for all users that will be using RVM:

# usermod -a -G rvm root

And run /etc/profile.d/rvm.sh:

# source /etc/profile.d/rvm.sh

You should now be able to run the rvm command. Try the following:

# rvm -v
rvm 1.26.11 (latest)

Any output that isn’t an error is good news! At the time of writing this, my RVM version is 1.26.11.

Ruby

Once RVM is installed, installing a specific version of Ruby is easy! For this tutorial, I’m going to use 2.2.2. If your project requires a different version, replace 2.2.2 with that version.

We can install Ruby version 2.2.2 using RVM:

# rvm install 2.2.2 --no-docs

--no-docs tells RVM to skip some of the files it would normally download. We don’t need these, and it speeds up our installation. If you’d like, just remove that flag and RVM will install those files as well.

Now go get a coffee. This takes a few minutes!

Once it’s installed, we’ll make sure we’re always using version 2.2.2:

# rvm use 2.2.2
# rvm --default 2.2.2
# ruby -v
  ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]

We’re now up and running with a fresh installation of Ruby 2.2.2.

Rails

Of course, rails installation is simple.

# gem install rails
# rails -v
  Rails 4.2.3

Puma

Start by cloning your repository. If you don’t have one, you can make a new one in /var/www/html with rails new.

# cd /var/www/html
# git clone [email protected]:username/repositoryname.git

Add the following gems to your Gemfile.

gem 'puma'         # rails server
gem 'therubyracer' # javascript interpreter for CentOS

And install

# bundle install

Configuring the Webserver

Now we’ll configure puma and nginx. We’ll need a new nginx configuration, and want to remove the default:

# cd /etc/nginx/conf.d/
# mv default.conf default.bak
# nano rails.conf

And enter the following:

upstream rails {
  server localhost:3000; # Puma is running here
}

server {
  listen 80 default;
  server_name 104.131.56.255; # YOUR IP HERE

  location / {
    proxy_pass http://rails;
  }
}

Restart nginx and run your rails server as normal. You’ll see that Puma starts with the rails server.

# nginx -s reload
# rails server
  => Booting Puma
  => Rails 4.2.3 application starting in development on http://localhost:3000
  => Run `rails server -h` for more startup options
  => Ctrl-C to shutdown server
  Puma 2.3.2 starting...
  * Min threads: 0, max threads: 16
  * Environment: development
  * Listening on tcp://localhost:3000

Now visit your IP address in your browser. You should see the rails welcome page!

Next Steps

There are a few things left to do before your app is ready for use.

  1. Right now, if the server crashes or is rebooted, nginx and puma will not restart. They need to be daemonized. CentOS has a tool for this called chkconfig. There are plenty of tutorials out there on how to set these up, and scripts on the nginx documentation site to help with nginx’s daemon.

  2. You’ll also have to point the DNS for your domain at the server. nginx will check the server_name of incoming requests, but if the requests never end up there in the first place, you’ll only ever be able to access the website through the ip. Your domain provider can assist you with this.

  3. Your app will probably also need SSL. SSL setup with nginx is easy, but you must first obtain a certificate from a certificate signing authority (CSA). Whoever you’ve purchased your domain from can probably help you obtain an SSL certificate.