
Deploy your Rails App faster with Mina, Phusion Passenger, Ngnix and MySQL on Ubuntu 14.04
Taking your hard work from localhost to the public domain is blissful for every developer. When you want to make your app available to the outside world, you can have many options and questions. Which application server to choose? which deployment tool is fast or easy? what about the web server?
You will get answers to all those questions here. Let’s first have a brief introduction of all these tools and then we will see how to use them effectively to make deployment easy and faster.
Mina.
Mina is a server automation tool or auto deployment tool. When you search for auto deployment tool, you will majorly have two options – Capistrano and Mina. I have deployed apps using Capistrano and its an awesome tool. But, now I am using Mina as it is much faster than Capistrano.
I am using Mina as it is much faster than Capistrano!
You may have questioned why it is faster? Mina generates the whole process as a bash script and runs remotely into the server using a single SSH session. While in Capistrano each command runs in the separate SSH session.
Passenger.
A passenger is better at handling high volume traffic than other app servers like unicorn or puma and who doesn’t want to have high volume traffic? We will be using Nginx as the web server.
Now, let’s start deployment!
I am assuming you have already purchased instance from AWS or DigitalOcean and have a root user and IP of the server.
Setting Up Your Server.
Step 1: Login as root using SSH.
Before we do anything, let us add a new user named as deploy and give it a root permission. You need to login to remote server using SSH from your local machine.
ssh root@SERVER_IP_ADDRESS
If this is the first time your machine will not recognize the server you are logging into and will ask for your permission. Simply type yes and go ahead.
Step 2: Create a new user and give root permission.
adduser deploy
You will be asked to add the password. Pick a strong password. Now, give this user sudo
permissions.
gpasswd -a deploy sudo
Type exit and login again as deploy user using deploy@SERVER_IP_ADDRESS
to check if everything works as expected.
Step 3: Create a new folder where your application will reside.
Check your current directory using PWD
command and create the folder using below commands:
$ sudo mkdir -p your-app-name
$ sudo chown deploy:deploy your-app-name
This will create new folder in /home/deploy and adds permissions to it.
Setting Up Our Environment For Rails.
We will be using rbenv
to install ruby and manage Ruby versions. You may have questioned why can’t we use RVM? rbenv is lighter than RVM and we are not going to create gemsets and we don’t want to manage gemsets. It also doesn’t have many configurations. Let’s install rbenv
:
Step 1: Installing rbenv.
First, we need to update the installation package cache. Make sure you are logged in as deploy
user and type below command and hit enter.
sudo apt-get update
Now, install the rbenv using below command.
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
Now, install rbenv with the following commands:
$ cd
$ git clone git://github.com/sstephenson/rbenv.git .rbenv
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
$ git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
$ echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bash_profile
$ source ~/.bash_profile
Step 2: Install Ruby.
Install ruby with the following commands:
rbenv install -v 2.3.0
rbenv global 2.3.0
The first command will install Ruby and second command will set the global version of Ruby, or the version that will be used in all of our shells.
You can check if ruby installed properly and set it using below command.
ruby -v
Step 3: Install Bundler and configure Javascript Runtime.
Let’s configure it so that RubyGems will not install documentation locally for every gem that we install:
echo "gem: --no-document" > ~/.gemrc
Now, install bundler
gem install bundler
Rails need Javascript runtime as asset pipeline depends on it. So, we need to install node.js
for it. Install node.js
using below command:
$ sudo add-apt-repository ppa:chris-lea/node.js
$ sudo apt-get update
$ sudo apt-get install nodejs
Step 4: Configure Git and SSH key.
We need to add server’s public key to GIT or Bitbucket as deployment keys to clone the repository to the server. You can generate ssh key using below command.
ssh-keygen
This will create .ssh
folder in your home directory and create public and private key pair.
Copy your public key via cat /home/deploy/.ssh/id_rsa.pub
. Then, go to GitHub/Bitbucket, open your settings and add this new SSH key.
Step 5: Installing MySQL.
Use below commands to install MySQL:
sudo apt-get update
sudo apt-get install mysql-server mysql-client libmysqlclient-dev
You will be asked to enter the username and password while installing MySQL. Remember the credentials as they needed when we will configure the database.
Create a database which we will be using in a database.yml
file after initial set up. Follow below commands to create the database. You need to enter the password which you set while installing MySQL:
$ mysql -u root -p
Enter password:
mysql> CREATE DATABASE myapp-db;
Now, exit from DB console using the exit
command.
Now, we will install and configure Passenger and Nginx:
Install and Configure Phusion Passenger and Ngnix.
Step 1: Installing Passenger and Nginx.
First, we need to install PGP key:
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 561F9B9CAC40B2F7
Create an APT source file:
sudo nano /etc/apt/sources.list.d/passenger.list
This will open an empty file. Add below line to this file:
deb https://oss-binaries.phusionpassenger.com/apt/passenger trusty main
Save and exit with CTRL + X
, then Y
, then ENTER
.
Update the owner and permissions of the file:
$ sudo chown root: /etc/apt/sources.list.d/passenger.list
$ sudo chmod 600 /etc/apt/sources.list.d/passenger.list
Now, install Passenger with Ngnix:
$ sudo apt-get update
$ sudo apt-get install nginx-extras passenger
This last bit may overwrite the Ruby version to an older one. If so, you need to remove the incorrect Ruby location and create a new symlink to the correct Ruby binary file:
$ sudo rm /usr/bin/ruby
$ sudo ln -s /usr/local/bin/ruby /home/deploy/.rbenv/shims/ruby
Step 2: Configuring the Nginx.
Open the Nginx configuration file in your text editor:
sudo nano /etc/nginx/nginx.conf
Find and uncomment the following lines or add below lines in http block:
passenger_root /usr/lib/ruby/vendor_ruby/phusion_passenger/locations.ini;
passenger_ruby /home/deploy/.rbenv/shims/ruby;
Save and exit with CTRL + X
, then Y
, then ENTER
.
Now, disable the default Nginx configuration.
sudo nano /etc/nginx/sites-available/default
Comment out the following two lines in server
block. Save and exit.
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
Now we need to create a custom Nginx configuration file for our app:
$ sudo nano /etc/nginx/sites-available/your-app-name
To this file, we need to add a below server block:
server {
listen 80 default_server;
server_name SERVER_IP_ADDRESS;
passenger_enabled on;
passenger_app_env production;
root /home/deploy/your-app-name/current/public;
}
Save and exit with CTRL + X
, Y
, ENTER
.
Create a symlink for it:
sudo ln -s /etc/nginx/sites-available/your-app-name /etc/nginx/sites-enabled/your-app-name
Restart the Nginx.
sudo nginx -s reload
Setup Mina to Deploy your App on Server.
Please note that now we are doing all the operations in our local machine, not on the server.
Step 1: Install Mina gem and configure it
You don’t necessarily add gem into gem file. You can install it using below command:
gem install mina
Then run:
mina init
It will generate deploy.rb
file in config
folder which contains the basic configuration of deployment. Here is the file with all required configuration.you can edit it as per your need.
In this file, we have added database.yml
, application.yml
, log
folder, and tmp
folder in a shared path to copy them to a server.
Now, run the following command in your app directory for initial setup.
Step 2: Set up Mina.
mina setup
This will ask for your remote server’s password. Enter it and hit enter.
This will automatically log in to the server and create two folders shared
and releases
inside /home/deploy/your-app-name
directory.
This will save database.yml
and application.yml
to /home/deploy/your-app-name/shared/config
folder.
Log in to a server using deploy
user and edit content of database.yml
and set your configuration.
production:
adapter: mysql2
encoding: utf8
database: myapp-db
username: root
password: root
pool: 10
reconnect: true
Here, application.yml
is the file created using Figaro gem.
Now, its time to deploy our application after long configuration. Use below command in your application directory and in your local machine.
mina deploy
The first time it will take a bit more time but after the initial set up it will make your deployment much faster!
Also, this command will create a new directory currently in /home/deploy/your-app-name
If everything works as expected you can visit your SERVER_IP_ADDRESS
in the browser like this http://SERVER_IP_ADDRESS
and you can see your beloved application!
Thank you for reading!
At BoTree Technologies, we build enterprise applications with our RoR team of 25+ engineers.
We also specialize in RPA, AI, Python, Django, JavaScript and ReactJS.
Consulting is free – let us help you grow!
