Set up VPS for Rails Deployment: Ubuntu, UFW, Nginx, Postgresql and Ruby

Intro

I am a fan of setting up my deployment pipeline before starting on a project. It gives me a quick win out of the gate and moving forward I know all I need to focus on is the code.

In this series we will tackle the following:

  • Setup a new Linode VPS
  • Setup a barebones Rails 5.1 app with ReactJS
  • Use Bitbucket to host our code repository
  • Configure Capistrano
  • Setup a free Codeship account for Continuous Integration (CI) and Continuous Deployment (CD)

In this article we will begin by setting up a new Linode VPS and get a basic configuration up and running.

Linode VPS

You could use any vps server, but I will be using Linode for its $5 plan. This plan gives you 1GB ram instead of the 512mb most other vps hosts offer.

We will deploy an Ubuntu 16.04 LTS image for our OS.

You will now want to boot your new image, so we can ssh in and get it configured.

Now you can go to the remote access tab and get your ssh info.

$ ssh root@69.164.214.184

We first want to create our user we will use to deploy, so we will create a user of: deploy

# adduser deploy

The deploy user will need to run some items that need root privileges, so we will add them to the sudo group.

# usermod -aG sudo deploy

If you don't already have a ssh key generated on your local machine you will want to do that now.

$ ssh-keygen

Let's copy up our local ssh key to our Linode server as the deploy user.

$ ssh-copy-id deploy@69.164.214.184

After it is copied over you should now be able to ssh in as the deploy user without needing to type in the password. Verify you can do that before we move on.

We are now going to disable password authentication into the server.

Run these ssh'd in as the deploy user.

$ sudo vim /etc/ssh/sshd_config

In this file find PasswordAuthentication and change it from yes to no.

# Change to no to disable tunnelled clear text passwords
PasswordAuthentication no  

Reload the ssh daemon to get this setting change to take affect.

$ sudo systemctl reload sshd

Password authentication is now disabled and the only way in is with ssh key authentication.

Next we will enable Ubuntu's UFW firewall. We will want to first make sure the firewall is set to allow ssh connections in. If not we will not be able to get back in the system. I've definitely done this before and it is not fun to have to start over from scratch.

$ sudo ufw allow OpenSSH
$ sudo ufw enable

You can now check the status of the firewall to make sure ssh is allowed.

$ sudo ufw status

Installing Ruby

We will now get ruby set up on our Linode VPS.

First off let's make sure sure we have dependencies installed for Ruby.

$ sudo apt-get update
$ 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

We are going to manage our Ruby version with rbenv

$ git clone https://github.com/rbenv/rbenv.git ~/.rbenv
$ cd ~/.rbenv && src/configure && make -C src

If that second line fails, it's okay everything will still work.

$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(rbenv init -)"' >> ~/.bashrc
$ source ~/.bashrc
$ type rbenv
rbenv is a function  
rbenv ()  
{

Let's install a couple rbenv addons to make working with it easier. The first will be ruby build which gives us the rbenv install command. The second will be rbenv-gemset. This will give you a way to organize your gems.

$ git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
$ git clone git://github.com/jf/rbenv-gemset.git $HOME/.rbenv/plugins/rbenv-gemset

We can now get Ruby installed. Yay!

$ rbenv install 2.4.1
$ rbenv global 2.4.1
$ ruby -v
ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-linux]  

Let's get bundler installed under our new global version of Ruby.

$ gem install bundler

Installing Nginx

$ sudo apt-get install nginx

With Nginx installed we need to adjust the UFW firewall to allow access to the service.

$ sudo ufw allow 'Nginx HTTP'

You can now go to the ip address of your server in a browser and you should see that Nginx is up and running properly.

Installing Postgresql

$ sudo apt-get install postgresql postgresql-contrib

Once this finishing installing we can switch over to the postgres user and get our deploy user setup.

$ sudo -i -u postgres
postgres@localhost:~$ createuser --interactive  
Enter name of role to add: deploy  
Shall the new role be a superuser? (y/n) y  

Conclusion

There will be more configuration on the server in later sections, but we now have a good base moving forward. In the next section we will work on getting the rails app setup for deployment.