How to Install and Configure Ruby With Rbenv, Rails, MariaDB, Nginx, SSL and Passenger on Ubuntu 17.04

Published on: Tue, Nov 7, 2017 at 10:21 am EST
Linux Guides Programming Ruby Ubuntu

Ruby on Rails is a popular web framework for Ruby that was developed to increase a programmer's productivity. However, getting various gems and dependencies to work together can get tricky sometimes. This guide will help you set up a full production-ready Rails environment including commonly used gems and dependencies.

Requirements

  • Vultr instance with at least 512 MB of RAM (1024 MB prefered).
  • Vultr instance running Ubuntu 17.04.

Stack Used in This Guide

  • Nginx: a fast and powerful web server. (ver 1.10.3)
  • Passenger: an app server that will help Nginx serve your Ruby app. (ver 1.5.1.8)
  • Rbenv: a Ruby version manager. (ver 1.1.1-2)
  • Ruby: (ver 2.4.1)
  • MariaDB: an open source branch of MySQL server (ver 10.2)
  • SSL certificate from Let's Encrypt

Installation

Add Sudo User

Note: It is highly recommended to not install any of these services as root, as you might expose yourself to an attack. Setting up a deploy or app user is a common convention:

sudo adduser deploy
sudo adduser deploy sudo
su deploy

Update and Upgrade System

Make sure you are running all the latest packages on your Ubuntu VM:

sudo apt-get update && sudo apt-get upgrade -y

Install Build System

In order to be able to compile Ruby using rbenv and other gems, various packages need to be installed. Depending on the version of Ruby you will need, some of the packages may not be needed.

Compiling
sudo apt-get install -y curl zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev
sudo apt-get install -y libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev libcurl4-openssl-dev
sudo apt-get install -y python-software-properties libffi-dev
sudo apt-get install -y build-essential openssl libreadline6 libreadline6-dev libreadline-dev
sudo apt-get install -y automake libtool bison pkg-config bison autoconf libc6-dev ncurses-dev
sudo apt-get install -y libapr1-dev libaprutil1-dev libx11-dev libffi-dev tcl-dev tk-dev
Packages for SSL support

These are necessary to compile several gems, such as Passenger:

sudo apt-get install -y zlib1g zlib1g-dev libssl-dev libyaml-dev libcurl4-openssl-dev libruby
Versioning

The Ruby community is using Git as a SCM of choice; but additional ones, like Mercurial or Subversion, can be installed as well:

sudo apt-get install -y git git-core
Database Drivers for MySQL / MariaDB
sudo apt-get install -y libmysqld-dev mysql-client libmysqlclient-dev
Nokogiri

Required for several popular gems that need native XML libs:

sudo apt-get install -y libxml2-dev libxslt-dev
Node.js

Add official repositories from Node with the latest version as default Ubuntu repositories tend to lag behind a few major versions:

curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
sudo apt-get install -y nodejs

Optional Packages

These packages are not required for the system to run, but are good to have if you need to use certain gems.

Graphs and Images

These libraries are not necessary and can be skipped unless you plan on using image manipulation gems; such as Rmagick:

sudo apt-get install -y imagemagick libmagickwand-dev libvips-dev

Database Drivers for SQLite and PostgreSQL

Install drivers for SQLite or PostgreSQL if you need to connect to other databases or prefer a simple, local DB:

sudo apt-get install -y libsqlite3-dev sqlite3  libpq-dev postgresql postgresql-contrib

Tools

Utilities that don't normally come pre-installed on a fresh Ubuntu install. Feel free to install your text-editor of choice:

sudo apt-get install -y iotop htop nano vim

Install the MariaDB Server

MariaDB is a powerful relational SQL server, that is fully compatible with MySQL. The easiest way to install the latest version of MariaDB is using official repositories:

sudo apt-get install software-properties-common
sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xF1656F24C74CD1D8
sudo add-apt-repository 'deb [arch=amd64,i386] http://ftp.utexas.edu/mariadb/repo/10.2/ubuntu zesty main'
sudo apt update
sudo apt install -y mariadb-server

Follow the prompts and set up a root password. After, verify that you can access your fresh installation:

mysql -V 

It will display a line similar to this:

mysql  Ver 15.1 Distrib 10.2.8-MariaDB, for debian-linux-gnu (x86_64) using readline 5

Login into the MySQL shell:

mysql -h localhost -u root -p 

Note: use \q to exit.


Install Rbenv and Ruby

Rbenv

Install Rbenv using git. This is the simplest install method, and it allows for easy updates later. Also install ruby-build, it is responsible for actually compiling different versions of Ruby:

cd
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build

Note: When you need to update simply cd ~/.rbenv and git pull.

Make Rbenv and Ruby-build available in the shell. To ensure that the export lines get inserted at the beginning of the .bashrc file, which is important for non-interactive bash commands, use these lines:

echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.temp_bashrc
echo 'eval "$(rbenv init -)"' >> ~/.temp_bashrc
echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.temp_bashrc

cat ~/.temp_bashrc ~/.bashrc > ~/.combined_bashrc && mv ~/.combined_bashrc ~/.bashrc && rm ~/.temp_bashrc

exec $SHELL

Check if Rbenv and Ruby-build installed and are available in shell:

rbenv install --list

If rbenv is not recognized, log out and log back into the shell.

Create a ~/.bash_profile file and point it to source your ~/.bashrc file. If you need to run any non-interactive shell commands from your Rails app, such as cron jobs setup by the whenever gem, it will use the same version of Ruby as your interactive shell. This can help prevent strange errors. Add this line to the ~/.bash_profile file:

if [ -f $HOME/.bashrc ]; then
        source $HOME/.bashrc
fi

Ruby

Install Ruby 2.4.1:

rbenv install 2.4.1

Note: This process may take 5-15 minutes depending on the resources on your VM, and there is no progress bar.

Make Rbenv available everywhere.

rbenv global 2.4.1

Passenger and Nginx

Add the PGP key and HTTPS support for apt:

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

Add the Passenger repository:

sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger zesty main > /etc/apt/sources.list.d/passenger.list'
sudo apt-get update

Install the Passenger + Nginx modules:

sudo apt-get install -y nginx
sudo apt-get install -y libnginx-mod-http-passenger

Visit your Vultr instance using it's domain name or IP to test these at this point. If they're working, your page will show the default Nginx welcome page.

Setup Rails, the App, and Configure Passenger

Install Bundler and Rails:

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

Ubuntu/Debian convention is to setup your app in /var/www. By default it is only writable by root. For the setup to work, give ownership to the sudo user deploy:

sudo chown deploy:deploy /var/www -R

Generate the rails app in /var/www/ . If you already have an app you want to deploy, git clone it here and then run bundle:

cd /var/www
rails new example --database=mysql
Configure Passenger to point to the app.
  1. Prep Nginx.

    sudo nano /etc/nginx/nginx.conf
    
  2. Change user to deploy.

    user deploy;
    
  3. In the http section of the config, there should be a line that tells Nginx to load modules including passenger. If it's missing, you can add it right after Virtual Host Configs title, but before sites-enabled.

    include /etc/nginx/conf.d/*.conf;
    
  4. Edit/create the passenger.conf file.

    sudo nano /etc/nginx/conf.d/mod-http-passenger.conf
    
  5. Tell Passenger to use our Rbenv setup. It may contain a line pointing to the Ruby version included with Passenger, just delete or comment it out.

    passenger_ruby /home/deploy/.rbenv/shims/ruby;
    passenger_root /usr/lib/ruby/vendor_ruby/phusion_passenger/locations.ini;
    
  6. Setup virtual host to point to the app in /var/www/example/.

    sudo nano /etc/nginx/sites-enabled/example.conf
    
    
    server {
      listen 80;
      server_name example.com www.example.com;
      root /var/www/example/public;
      passenger_enabled on;
    
      # When you are ready to switch to production mode - change this to `production`
      passenger_app_env development; # <-- !important      
    }
    
  7. Restart Nginx.

    sudo service nginx restart
    

At this point your application is ready to be used in development mode. To switch to production mode you need go back to your Nginx configuration and change the rails_env setting to production.

Before you switch to production mode, you still will need to setup your production database example_production, database.yml, and secret key. Check out a tool like Capistrano or Mina to speed up your application deployment process. It is a good practice to use ENV variables with a gem like dotenv, and do not commit your passwords, secret keys and such to your git repository.

Setup SSL

There are multiple services out there offering SSL certificates for your domain, many are paid and a couple are free. Setup SSL no matter what service you use. Let's Encrypt is very easy, and free, to use. Let's Encrypt is a non-profit organization backed by many tech giants.

Installation

Run the following commands, and follow the prompts.

sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python-certbot-nginx
sudo certbot --nginx
sudo certbot renew --dry-run

If you go to your Vultr instance now using HTTPS, you will see a secure website.

Renewal

Your newly issued certificate will expire, and will need to be renewed periodically. The easiest way to do this is to set up a cron job.

sudo crontab -e 
30 2 * * 1 /usr/bin/certbot renew 

As a final, but optional step, reboot your VM and make sure all services restart as expected.

Want to contribute ?

You could earn up to $300 by adding new articles