Deploying Rails apps using Capistrano

Capistrano Logo Deploying your application to the web is not a one-time thing. There will be changes to the application code, new assets to include, database updates, and so on. Applying these changes to your web server includes a list of commands that we need to do every time we need to deploy.

Capistrano solves this problem by automating the deploy process so you can execute all of the steps in a single command. Automation prevents user errors while deploying like forgetting the precompile task when assets have changed, missing database migrations, and remembering the sequence of commands. Automation also enables your infrastructure to scale so that your code is automatically deployed to all application servers without logging in to each one to manually deploy your code.

In order to use Capistrano, you need to set up your web server first (we will use Nginx in this article). If you have already done this, please skip the first section of the article and proceed to installing and setting up Capistrano.

Note: This article assumes that you have already set up your server and are using Ruby on Rails as your application framework.

Nginx

Installation

We will install Nginx via the Passenger gem.

In order to do this, we need root privileges. If you are using RVM, it already provides a sudo command called rvmsudo, but if you are using rbenv, you need to install the rbenv-sudo plugin first:

git clone git://github.com/dcarley/rbenv-sudo.git ~/.rbenv/plugins/rbenv-sudo

We then install the passenger gem by adding this line to our Gemfile:

gem 'passenger'

Then install the gem and its binaries:

bundle install

And if you are using rbenv, update with the newly installed binaries:

rbenv rehash

We are now ready to install Nginx via Passenger:

If you are using RVM:

rvmsudo passenger-install-nginx-module

If you are using rbenv:

rbenv sudo passenger-install-nginx-module

Compared to installing Nginx via the Ubuntu package manager (sudo apt-get install nginx) this method of installing Nginx does not provide the start and stop scripts so we can conveniently control the web server process. Thus we need to manually provide this init script in our system:

wget -O init-deb.sh https://raw.github.com/JasonGiedymin/nginx-init-ubuntu/master/nginx
sudo mv init-deb.sh /etc/init.d/nginx

There is a small change that needs to be done in our init script, which is to specify the location of the Nginx install. By default this is located at /opt/nginx, so we set it accordingly:

sudo nano /etc/init.d/nginx

NGINXPATH=${NGINXPATH:-/opt/nginx}      # root path where installed

We make our init script executable:

sudo chmod +x /etc/init.d/nginx

Then we also set it so that Nginx runs automatically when you reboot the system:

sudo /usr/sbin/update-rc.d -f nginx defaults

Rails application server block

We will place all our application code in /var/www/. Make sure that the deploy user that we created has read and write access to this directory.

Next we need to configure Nginx so that it runs our code in /var/www/. Nginx provides a simple way to organize our server configuration in server “blocks” which is very useful especially if we are running multiple applications in the same server. It will look for additonal configuration in the /etc/nginx/sites-enabled directory and includes it when running the web processes.

However, we will not be putting our configuration directly in /etc/nginx/sites-enabled, instead we will create them in the /etc/nginx/sites-available directory. In this example, we assume we have a Rails application called myrailsapp.

Create and edit a new file called myrailsapp.conf in the sites-available directory:

sudo nano /etc/nginx/sites-available/myrailsapp.conf

In the empty file, put in the following:

server {
  listen       80;
  server_name  mydomain.com www.mydomain.com;
  root /var/www/myrailsapp/current/public;
  # passenger_min_instances 4;

  location / {
    passenger_enabled on;
  }
}

If you are using SSL certificates for your domain, place the certificate/certificate bundle and the key file in the /etc/nginx/ssl directory, then add the following as well in the myrailsapp.conf file:

server { listen 443; server_name mydomain.com www.mydomain.com; root /var/www/myrailsapp/current/public; # passenger_min_instances 4; ssl on; ssl_certificate /etc/nginx/ssl/mydomain_bundle.crt; ssl_certificate_key /etc/nginx/ssl/mydomain.com.key; # Forward secrecy settings ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS +RC4 RC4"; location / { passenger_enabled on; } } read more

Install Ruby on Rails on Ubuntu

Ruby_on_Rails-logoAfter you set up your server, its time to deploy applications into it. One of the most popular web application frameworks is Ruby on Rails. This is built using the Ruby programming language and it enables developers to create web applications ranging from quick prototypes and Minimum Viable Products (MVPs) up to large distributed applications. Rails is an opinionated framework, meaning there is a standard way of doing things, but it can also be modified to suit your preferred architecture and coding style. By default however, Rails provides sensible and secure defaults that will help you run and deploy your applications quickly. Through using Ruby gems to augment functionality, you can create a fully-functional web application in a short amount of time.

We will start the process by setting up the dependencies needed for Ruby on Rails.

(Updated March 2018)

Install Git

Git is perhaps the most popular version control system today. By utilizing small functions and commands that do only one task (and does it well), it achieves tremendous flexibility and power.

Git is basically a command-line tool, however there are several graphical user interfaces (GUIs) built that support all major operating systems. A sample list can be found at https://git-scm.com/downloads/guis.

If you are using Ubuntu or any other Linux distribution, you can install git using the default package manager:

sudo apt-get install git

It is useful to specify global parameters in git, like your name and email address so that you do not need to specify it whenever you push to your repository.

git config --global user.name "Juan dela Cruz"
git config --global user.email "[email protected]"

To list the git configurations in your system:

git config --list

Install Ruby

Ruby is a programming language designed for developer happiness. It provides an elegant syntax that makes programming enjoyable. As Ruby on Rails is built on Ruby, we need to install Ruby itself in the system.

First we need to install the dependencies needed to compile and install Ruby. If you are using Ubuntu, this is as simple as the below command (other operating systems will have their equivalent packages):

sudo apt-get install git-core curl zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev libcurl4-openssl-dev python-software-properties libffi-dev

If you plan on using ImageMagick for image processing in your application, like if you have a photo upload feature that requires the image to be resized, you also need to install these dependencies:

sudo apt-get install imagemagick libmagickwand-dev

Managing Ruby versions

There are times when you need to run applications using different Ruby versions. In this case it is important to properly manage the Ruby versions installed in your system. Two of the most popular version managers are RVM and rbenv. As these two work essentialy the same, it is up to you which one you should choose to use. There are arguments that RVM muddles more on your system than rbenv, although personally I have used both in my projects and they both work quite well.

In this article we will use rbenv as our Ruby version manager. If you opt to use RVM instead, their website includes a tutorial on how to install RVM.

Basically we will fetch a predefined install script from the git repository and run that script in our system. Security-aware individuals may cringe at this method, but at the moment this is the simplest and quickest way to install programs.

git clone https://github.com/rbenv/rbenv.git ~/.rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
exec $SHELL

Then we install the script that makes it easy to build, compile and install Ruby:

mkdir -p "$(rbenv root)"/plugins
git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build

Once that is all set, we are now ready to install Ruby using rbenv:

rbenv install --list
rbenv install -v 2.4.3
rbenv global 2.4.3

Just replace the version number with the Ruby version you want to install. You can also install Ruby from source but take note that doing this will install Ruby in your local system and will not be managed in rbenv.

Install Bundler and Rails

When you installed Ruby, the package manager called Rubygems is also installed by default. Rubygems lets you install Ruby libraries called gems that provide specific functionality that you can include in your application. Ruby on Rails, the application framework that we will use, is also packaged as a gem. Ruby Toolbox is an awesome tool to find gems depending on your desired usage, and ranks it by popularity or activity.

When installing Ruby gems, the documentation is also installed by default. While there are cases when this local documentation is useful, most of the time you can refer to the internet for the documentation when you need it. You can opt not to include the gem documentation when you install gems and this will make the install faster and will consume less disk space.

To exclude the documentation when installing gems, use this command:

gem install rails --no-rdoc --no-ri

As typing this whenever you install gems can be tedious, you can also make this as the system default. Add the –no-document flag to your gemrc file:

echo "gem: --no-document" > ~/.gemrc

Make sure that Rubygems is updated to the latest stable version:

gem update --system

Now we are ready to install Bundler and Rails

gem install bundler
gem install rails

Bundler makes it easy to manage gems in your application using a configuration file called a Gemfile where you specify which gems and versions your application uses.

After installing new gems, we need to tell rbenv to use the latest binaries/executables that are included in the new installs.

rbenv rehash

Install a Javascript runtime library

Ruby on Rails’ asset pipeline requires a Javascript runtime library to be installed as well. Therubyracer is a Ruby gem that you can use for this purpose, however, the gem’s size can be an issue.

I recommend installing NodeJS and use it as the runtime library. You can install it from source from their home page, or you can use Ubuntu’s package manager to install it for you:

Add the NodeJS repository so Ubuntu can fetch it:

curl -sL https://deb.nodesource.com/setup | sudo bash -
sudo apt-get update
sudo apt-get install nodejs

Set up the database

A fully-functional web application needs a database to run. There are many free and available databases available and you should pick one that suits your needs. Relational databases like MySQL and PostgreSQL and document-oriented databases like MongoDB are some of the most popular choices.

In this article we will set up either MySQL or PostgreSQL.

Install MySQL

In Ubuntu, its pretty straightforward to install MySQL:

sudo apt-get install mysql-server

During the installation process, it will ask for the root password. Take note of this root password as you will need it to set up your application later on.

The configuration file is located at:

/etc/mysql/my.cnf

By default no configuration is needed and the MySQL service should be up and running. If you edited the configuration file or just need to restart the service in case of an issue:

sudo service mysql restart

In case you misplaced the root password, you can re-set the password using this command:

sudo dpkg-reconfigure mysql-server-5.5

Just replace the version number with the one installed in your system.

Install PostgreSQL

In Ubuntu, install the following packages:

sudo apt-get install postgresql postgresql-contrib libpq-dev

During the installation process, it will set up a default user called postgres. We will use this default user to create the database user we will use in our applications. In this example, we will create the pguser user.

sudo -u postgres createuser -s pguser

We then change the password of pguser using the PostgreSQL console:

sudo -u postgres psql

Inside the console, type the following commands:

\password pguser
...
(change password prompt)
...

While we are in the console, we can also create the PostgreSQL database that our application will use, and set the pguser user as the database owner so we get full access:

CREATE DATABASE webapp_development OWNER pguser;
\q

Create a new Rails application

Now that we have Ruby and a database installed, we can now create our Rails application. Let’s start by calling Rails’ new command to set up our application (called “awesomeapp” in this example).

rails new awesomeapp

Rails will automatically generate files inside the “awesomeapp” folder that contains everything necessary to run your application. It will also try to run bundle install and install the default Ruby gems set by Rails.

Open the Gemfile in the application folder and add the database wrapper gem that you need to use:

source 'https://rubygems.org' gem 'rails', '4.2.4' # If you are using MySQL gem 'mysql2' # If you are using PostgreSQL gem 'pg' # If you are using MongoDB gem 'mongoid' gem 'bson_ext' ...(your other gems below)... read more