Amendment to a tutorial I wrote for an upcoming workshop in my city. This tutorial will use DigitalOcean and its one-click install Ruby + Rails + Nginx + Unicorn image as base. Sign up using this link for $10 free credit! This tutorial is aimed for Ruby on Rails developer who can't afford a PaaS like Heroku 💸, or want to learn how to setup rails on their own VPS.

In this tutorial we will setup a Ubuntu cloud VPS and push a repository from your local machine to the cloud VPS. We will use fox_sample rails repository for this tutorial.

Disclaimer : I am no DevOps expert and the steps outlined in this tutorial might not be the best way to deploy.

Prerequisite

You will need a DigitalOcean account created as we will be using its one-click install apps for this tutorial.

Create the One-click Rails App droplet

First, log in to DigitalOcean Control Panel.

Select Create Droplet
create_droplet

Select One-click Apps
one-click-apps

Select Ruby on Rails on 14.04 image
As for the server size, 1GB memory is recommended but 512 MB would suffice for this tutorial.
rails

Next, select any additional settings such as private networking, IPv6, or backups.

Finally, select applicable SSH keys if you want to use for accessing this Droplet, and click the Create Droplet button.

Access your Rails droplet and setup

You can navigate to your newly created droplet ip address using your favorite web browser by typing http://server.ip.address.here, you will see rails is up and running.

default rails page

Once the droplet is created, two user accounts root and rails will be created. Lets login as root via ssh using the following command :

ssh root@server.ip.address.here

Replace server.ip.address.here with your server IP address. You will be prompted to input password that is sent to you by email if you didn’t specify ssh key during server creation. If it is your first time connecting to ther server, you will be prompted about host authenticity, type yes and press enter.

After login, you will be shown the login credentials of the rails user and also the PostgreSQL credential like this :
rails credential
Copy this information to a text file as we will use it later.

Before anything else, update the apt-get repository

sudo apt-get update

Setup rails user privilege

Since root has all the privilleges, it might be dangerous to execute commands as root has the absolute power to do anything and might damage the system if not careful. Lets add sudo privilege to the rails user and also add it to the rvm user group so that multiple ruby versions will be available to the user.

gpasswd -a rails sudo

gpasswd -a rails rvm

We will also exempt some commands that normally requires sudo password input for the rails user, these commands will be used for the git post-receive hook later on.

Change current directory to sudoers.d :

cd /etc/sudoers.d/

and create a file named rails to correspond to the rails user.

nano rails

type in the following commands :

rails ALL=(ALL) NOPASSWD: /usr/sbin/service nginx start,/usr/sbin/service nginx stop,/usr/sbin/service nginx restart,/usr/sbin/service unicorn start,/usr/sbin/service unicorn stop,/usr/sbin/service unicorn restart 

Press Ctrl + X to quit and enter 'Y' to save. This will grant rails user permission to start/stop/restart nginx and unicorn server without typing password.

Type in the following chmod permission just in case,

chmod 0440 /etc/sudoers.d/rails

Increase swap size for gem installation (optional)

If you have selected 512 MB RAM previously, it is advised to increase the swap size as you might run out of memory for installation of some gem. You can skip this step if your server has 1GB RAM or more.



sudo dd if=/dev/zero of=/swap bs=1M count=1024

sudo mkswap /swap

sudo swapon /swap



Logout and login as rails user

Now logout and login as the rails user with the credential you saved earlier exit
ssh rails@server.ip.address.here
You can change the password of this user if you want to :
passwd

Install git and create a repository

Before this step, you should have login as rails user.

Install git using this command :

sudo apt-get install git

Install the dependency required by nokogiri gem :

sudo apt-get install libxslt-dev libxml2-dev



Upgrade the ruby gem to the latest version :

gem update --system



After installing Git, we will now create a bare git repository named fox_sample.git and a folder to store the source code fox_sample, let's put the repository on your user folder for this tutorial ( you can of course change to other location ).
cd ~rails

mkdir fox_sample

mkdir repo && cd repo

mkdir fox_sample.git && cd fox_sample.git

git init --bare



--bare indicates that the repository will have no working files / source code, just the version control.

You will have two directory created :

  1. /home/rails/fox_sample - the working tree
  2. /home/rails/repo/fox_sample.git - the version control repository

Next, we will dive into the git hooks to add a work tree directory (where your source code will be stored), more info about git hooks here . We will use the post-receive hook as it is executed after finished receiving git push.

In the repository directory fox_sample.git,
go to the hooks folder

cd hooks

Create a file named 'post-receive' :
nano post-receive


And paste this and save :


Remember to give execute permission to the post-receive hook : chmod +x post-receive

Previously we added Nginx service and Unicorn service into sudoers.d/rails to exempt from entering password, it is used here for deploying tasks so that the deployment task will not be paused to ask for password when we git push.

We will configure Unicorn and Nginx config file before pushing a local rails app to this server.

Configure Unicorn

By default, the Unicorn server is pointing to the default rails app which we saw at the start of this tutorial. We will change the Unicorn configuration file to point to our fox_sample directory.

Open /etc/unicorn.conf and edit it: sudo nano /etc/unicorn.conf

Find the line that mentions working_directory, and replace it to point to your application. Replace rails_project with fox_sample. When you're done, the line should look like this :
/etc/unicorn.conf excerpt
  working_directory "/home/rails/fox_sample"

Next, open and edit /etc/default/unicorn sudo nano /etc/default/unicorn

Find the line that mentions APP_ROOT, and replace it to point to your application. Replace rails_project with fox_sample. When you're done, the line should look like this:

/etc/default/unicorn excerpt
  APP_ROOT=/home/rails/fox_sample

We will also add another environment variable for the database credential for the app at the bottom of the same file:
/etc/default/unicorn excerpt
  # database password shown in setup step
  export FOX_SAMPLE_DATABASE_PASSWORD=Uxf1NRZfjH

Next, we will configure the Nginx config files.


Configure Nginx

Nginx which is used as a reverse proxy to Unicorn, needs to know the path of your application's public directory. Open and edit the Nginx configuration file:
sudo nano /etc/nginx/sites-enabled/rails


Find the line that mention root, and change it to point to the fox_sample app's public directory. The line should look like this after editing:

/etc/nginx/sites-enabled/rails excerpt
  root /home/rails/fox_sample/public;

Save and exit.

Push local git repository to server and deploy

This step will be performed on your local computer. Navigate to your favorite directory and git clone the fox_sample rails repo :
git clone https://github.com/cupnoodle/fox_sample.git

Navigate to the cloned repository cd fox_sample

Add a git remote named live that points to your server repository location:
  git remote add live ssh://rails@YOUR_SERVER_IP_OR_DOMAIN_NAME/home/rails/repo/fox_sample.git

And now you are set to deploy to the server , just push it to the server and you are good to go : git push live master

Now head to http://you.server.ip.address , you should see similar output below :

My feel when successfully deployed rails

Congratulations 🎉🍻! You have successfully deployed a Rails application using git push from your local machine to the remote VPS.

For subsequent changes, just git commit and then git push live and your server will run the deploy task automatically.