Deploying Rails app

Introduction

In this article you will learn how you can deploy your Rails app to a server together with Capistrano and how to make service for Rails app.

First, we have to transfer our application’s code to the git repo. Next step is to make user for our application on server:

Preparing Server

We need to add new user for app and prepare envirement: Login to your server with SSH:

Adding User on Server and Key Authentications

Add user

adduser rails_app

We need add rails_app user to sudo group:

adduser rails_app sudo

After adding user go and login to server:

$ su rails_app -l

We have to generate SSH key for user:

$ ssh-keygen -t rsa

Get the key from the server where we will deploy the app:

cat /home/rails_app/.ssh/id_rsa.pub

Copy and add the key to our git repository. Gitlab Deploy

…Also, we need to add public key from our local mashine and add it to server’s authorized_keys file:

$ nano .ssh/authorized_keys

Install RVM

RVM is a command-line tool that allows you to install and configure multiple ruby versions on one system.

First of all, we have to install the rvm packages using the installer script.

Add the rvm key to the server as ruby_app user:

gpg2 --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3

…and install it:

\curl -sSL https://get.rvm.io | bash -s stable --ruby=2.5.1

Transferring Application Code to the Server

We will transfer our app code from gitlab repo to location on server with Capistrano deployment tool.

Capistrano Configuration

Capistrano is a remote server automation and deployment tool and we using it for all our deploys. To use it, we had to install Ruby and capistrano gem before.

Make project

First make directory on your local mashine where you’ll install Capistrano:

$ mkdir ~/project

…and enter the folder

$ cd ~/project

The next step is to generate all needed files with command:

$ cap install

Customize stages

In our case, we’ll use production stage,so we have to generate it:

cap install STAGES=production

Edit generated files

We added stage and we are going to edit generated files in our project:

config/deploy.rb and config/deploy/production.rb

Configuration of deploy file:

lock "~> 3.11.0"
set :format, :airbrussh
set :log_level, :error
log_file: "log/capistrano.log", color: :auto, truncate: :auto
set :keep_releases, 5

#Set envirement:
set :default_env, {
  path: "/home/rails_user/.rvm/gems/ruby-2.5.1/bin:/home/rails_user/.rvm/gems/[email protected]/bin:/home/rails_user/.rvm/rubies/ruby-2.5.1/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/home/rails_user/.rvm/bin:/home/rails_user/.rvm/bin
  IRBRC=/home/rails_user/.rvm/rubies/ruby-2.5.1/.irbrc",
  'GEM_HOME' => '/home/rails_user/.rvm/gems/ruby-2.5.1',
  'GEM_PATH' => '/home/rails_user/.rvm/gems/ruby-2.5.1:/home/rails_user/.rvm/gems/[email protected]'
}


set :keep_releases, 5

after "deploy:finished", "bundler:install"
after "deploy:finished", "bundler:migrate"
after "deploy:finished", "bundler:serve"

We will add every Rake task to his own file. In our case we are going to make bundler.rake file for bundler namespace in lib/capistrano/tasks/bundler.rake

# Adding Rake tasks

namespace :bundler do

  desc "Migrate database"
  task :migrate do
    on roles(:app), in: :sequence, wait: 1 do
      within release_path  do
        execute :bundle, "exec rake db:migrate"
      end
    end
  end


  desc "Install gems with bundle"
  task :install do
    on roles(:app), in: :sequence, wait: 1 do
      within release_path  do
        execute :bundle, "install"
      end
    end
  end

  desc "Rails Serve"
  task :serve do
    on roles(:app), in: :sequence, wait: 1 do
      within release_path  do
        execute :bundle, "exec nohup rails s &"
      end
    end
  end
end

Configuration of production.rb file:

set :stage, :production
set :branch, "master"
set :deploy_to, "/home/rails_user/"
set :repo_url, "ssh://[email protected]:posrt/inservio/rails-app.git"

server 'servername.com', user: 'rails_user', roles: %w{web app}, port: 22

Next step is to deploy your aplication:

$ cap production deploy

If, you want more informations about deploying with Capistrano tool you can check our article How we Deploy with Capistrano

Preparing the Rails App’s Environment

On our server, running on Debian Stretch, we have to config Nginx service, and add our own with systemd.

Nginx Configuration

In this case, in Nginx conf file we just need to put server name and location address to file, because Rails running own (puma server) service on 3000 port.

We are going to manage the Nginx webserver by adding new conf file:

$ nano /etc/nginx/sites-available/rails-app.com.conf

Add to config file proxy address and servername, so your file looks like this:

server {
  listen 80;

  server_name rails-app.com *.rails-app.com;      

  #We proxyed app to 3000 default port:
  location / {
    proxy_pass      http://127.0.0.1:3000;

	}
}

After making Nginx cong file, we are going to enable it:

$ ln -s /etc/nginx/sites-available/rails-app.com.conf /etc/nginx/sites-enabled/rails-app.com.conf

Nginx is now running and serving your app, but that only lasts until you restart it. Restart nginx service:

$ systemctl reload nginx.service

Adding Systemd Service

Wanted to have a rails service, because we need to manipulate with it. As root user we are going to create service file:

nano /lib/systemd/system/rails_app.service

And configure it like this:

[Unit]
Description=Rails App
Requires=network.target

[Service]
Type=simple
User=rails_user
Group=rails_user
WorkingDirectory=/home/rails_user/current/
ExecStart=/bin/bash -lc 'bundle exec rails server'
TimeoutSec=30
RestartSec=15s
Restart=always

[Install]
WantedBy=multi-user.target

Enable the service

systemctl enable rails_app.service

After we created file, have to start service:

$ systemctl start rails_app.service

Our Rails application is on server now and we can start to using it.

Welcome Rails