Deploying the Ruby on Rails One-Click Application from DigitalOcean

enquerer > Blog > Uncategorized > Deploying the Ruby on Rails One-Click Application from DigitalOcean
Deploying the Ruby on Rails One-Click-Application-from-DigitalOcean

Getting your Ruby on Rails application on to an Ubuntu server is a very time-consuming task. This is just because of the high amount of prerequisites required before starting your project on the Rails. You’ll have to start by installing Ruby and Rails followed by Puma, Nginx, Node.js, Postgres, etc. You would think if you had someone to do all that for you? Apparently, there’s someone for sure.

With the One-Click Application developed by DigitalOcean, you can easily get your Rails application on to an Ubuntu server.

Preinstalled Prerequisites

The One-Click application comes with a bundle of the following prerequisites that lay a foundation for your application hosting.

ComponentVersion
LinuxUbuntu 18.04.1
RubyLatest from rvm.io
RailsLatest gem package
PumaLatest gem package
NginxLatest from APT
Node.jsLatest from APT
PostgresLatest from APT
PostfixLatest from APT
CertbotLatest from APT

Other than the prerequisite package installations, the one-click application also provides the following:

  • It enables a UFW firewall permitting access only to SSH (port 22), HTTP (port 80), and HTTPS (port 443).
  • It creates a system user in the name rails which deploys the application.
  • It creates a database user in the name rails which the application uses to connect to the PostgreSQL.
  • It configures Ruby such that it uses vendored bundles and also installs all Gems and processes into the rails user.
  • It also configures the Nginx to forward the requests to a local UNIX socket which acts as a reverse proxy for application server.

Using a Blank Ubuntu Droplet?

If you already have a blank ubuntu droplet in hand, you can start configuring the prerequisites by following the steps in this tutorial. After completing the steps 1 to 4 in the tutorial, you can continue with our article for an easy application deployment.

Deployment

The one-click application comes with a pre-installed Ruby Version Manager (RVM) and a version of Ruby. The Rails and Ruby versions installed may be up-to-date, but we couldn’t confirm it (well, we received the application with an older version of Ruby and Rails). So, it’s mandatory to compare the installed versions with that in your local machine before continuing further.

If an older version is installed, use the following rvm commands to update them.

rvm install version-number{like:2.5.3}
rvm use 2.5.3 --default


Now, sign in to your Droplet using your SSH key (username@ipaddress). Enter your password and login to the Droplet.

Remaining of the article will be a step-by-step guide for an easy understanding of the process.

Step 1. Setting the SSH Key for Deployment

You will be using either Bitbucket or GitHub git for deployment.

If you’re using Bitbucket git on the Droplet, use the following command:

ssh -T git@bitbucket.org

If you are using GitHub, use this command instead:

ssh -T git@github.com

In both cases, you will be receiving a ‘Permission denied’ response. Then type the following command.

ssh-keygen -t rsa

The command will create an RSA key pair. When prompted for a passphrase, skip the line by pressing the Enter key. NEVER PROVIDE THE PASSPHRASE, as Bitbucket will deny permission during deployment.

Now, input the following cat command to display the public key.

cat ~/.ssh/id_rsa.pub

Copy the whole content of the key and paste it where you add the access key for your repository.

Now, clone your repository into your droplet with the following command.

git clone ssh://user@bitbucket.org/user/appname.git (in case of Bitbucket)
git clone https://github.com/user/appname.git (in case of GitHub)


Note: Remember to CHANGE HTTPS TO SSH when cloning with Bitbucket as it is a private repository.

Step 2. Adding Deployment Configurations in the Rails App

After cloning your repository into the droplet, create configuration files on your local machine for Nginx and Capistrano in your Rails application, by adding the following lines into the Gemfile in your Rails application.



group :development do


   gem 'capistrano',         require: false


   gem 'capistrano-rvm',     require: false


   gem 'capistrano-rails',   require: false


   gem 'capistrano-bundler', require: false


   gem 'capistrano3-puma',   require: false


end



gem 'puma'

After adding these lines and saving the Gemfile, run the following commands one by one.

bundle install
cap install

These will add some files into the application directory. Now, edit the capfile in your application root directory and add the following lines.


# Load DSL and Setup Up Stages


require 'capistrano/setup'


require 'capistrano/deploy'


require "capistrano/scm/git"


install_plugin Capistrano::SCM::Git



require 'capistrano/rails'


require 'capistrano/bundler'


require 'capistrano/rvm'


require 'capistrano/puma'


install_plugin Capistrano::Puma



# Loads custom tasks from `lib/capistrano/tasks' if you have any defined.


Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }

These lines will create a deploy.rb file in the config folder (config/deploy.rb). Edit the file and add the following lines into this file.


# Change these


server 'droplet_ip', roles: [:web, :app, :db], primary: true



set :repo_url,        'ssh://user@bitbucket.org/user/appname.git'


set :application,     appname


set :user,            'rails'


set :puma_threads,    [4, 16]


set :puma_workers,    0



# Don't change these unless you know what you're doing


set :pty,             false


set :use_sudo,        false


set :stage,           :production


set :deploy_via,      :remote_cache


set :deploy_to,       "/home/#{fetch(:user)}/#{fetch(:application)}"


set :puma_bind,       "unix://#{shared_path}/tmp/sockets/#{fetch(:application)}-puma.sock"


set :puma_state,      "#{shared_path}/tmp/pids/puma.state"


set :puma_pid,        "#{shared_path}/tmp/pids/puma.pid"


set :puma_access_log, "#{release_path}/log/puma.error.log"


set :puma_error_log,  "#{release_path}/log/puma.access.log"


set :ssh_options,     { forward_agent: true, user: fetch(:user), keys: %w(~/.ssh/id_rsa.pub) }


set :puma_preload_app, true


set :puma_worker_timeout, nil


set :puma_init_active_record, true  # Change to false when not using ActiveRecord



## Defaults:


# set :scm,           :git


# set :branch,        :master


# set :format,        :pretty


# set :log_level,     :debug


# set :keep_releases, 5



## Linked Files & Directories (Default None):


# set :linked_files, %w{config/database.yml}


# set :linked_dirs,  %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}



namespace :puma do


 desc 'Create Directories for Puma Pids and Socket'


 task :make_dirs do


   on roles(:app) do


     execute "mkdir #{shared_path}/tmp/sockets -p"


     execute "mkdir #{shared_path}/tmp/pids -p"


   end


 end



 before :start, :make_dirs


end



namespace :deploy do


 desc "Make sure local git is in sync with remote."


 task :check_revision do


   on roles(:app) do


     unless `git rev-parse HEAD` == `git rev-parse origin/master`


       puts "WARNING: HEAD is not the same as origin/master"


       puts "Run `git push` to sync changes."


       exit


     end


   end


 end



 desc 'Initial Deploy'


 task :initial do


   on roles(:app) do


     before 'deploy:restart', 'puma:start'


     invoke 'deploy'


   end


 end



 desc 'Restart application'


 task :restart do


   on roles(:app), in: :sequence, wait: 5 do


     invoke 'puma:restart'


   end


 end



 before :starting,     :check_revision


 after  :finishing,    :compile_assets


 after  :finishing,    :cleanup


 after  :finishing,    :restart


end



# ps aux | grep puma    # Get puma pid


# kill -s SIGUSR2 pid   # Restart puma


# kill -s SIGTERM pid   # Stop puma

After adding these lines and saving the file, create a new file in the config folder named nginx.conf (config/nginx.conf) and add the following line to the file.


upstream puma {


 server unix:///home/rails/appname/shared/tmp/sockets/appname-puma.sock;


}



server {


 listen 80 default_server;


 server_name _;



 root /home/rails/appname/current/public;


 access_log /home/rails/appname/current/log/nginx.access.log;


 error_log /home/rails/appname/current/log/nginx.error.log info;



 location ^~ /assets/ {


   gzip_static on;


   expires max;


   add_header Cache-Control public;


 }



 try_files $uri/index.html $uri @puma;


 location @puma {


   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;


   proxy_set_header Host $http_host;


   proxy_redirect off;



   proxy_pass http://puma;


 }



 error_page 500 502 503 504 /500.html;


 client_max_body_size 10M;


 keepalive_timeout 10;


}

After saving the nginx.conf file, create your secret key base in your local machine using the following command.

rake secret

Now, copy the generated key and paste it into the secrets.yml file in the config folder (config/secrets.yml) as in the following example.

Production:
  Secret_key_base: asdja1234sdbjah1234sdbjhasdbj1234ahds…

If the secret key base is not provided, there are chances to get a ‘secret key base missing error’ during migration in production.

Step 7. Updating Changes in Your Repository

Next, update the changes in your repository by running the following commands one by one.


git init

git add .

git commit -m “initial”

git push -u origin master

Now, run the bundle install command inside your application directory in the droplet.

 bundle install

Make sure that you created a production database in your droplet using the following command inside the droplet.

RAILS_ENV=production bundle exec rake db:create

After that, run the following command in your local machine to deploy the initial version of your application.

 cap production deploy:initial

The process will take some time to complete, including bundling and migration.

Step 8. Change Your Server Root

To change the server root on your droplet, run the following command:

sudo rm /etc/nginx/sites-enabled/example
sudo ln -nfs "/home/deploy/apps/appname/current/config/nginx.conf" "/etc/nginx/sites-enabled/appname"

Now, restart the server and run the following:

sudo service nginx restart

Wrapping Up

The one-click application helps you easily start developing on your Rails application. Although this tutorial is a helper to move forward, you may encounter various deployment issues while working on your project in the production environment, may be due to the Gems we use in our application or various other reasons. Hence, the production and deployment should be carried out in great care and concentration, so that you can avoid a great deal of possible errors and issues.

Hope you liked our tutorial. We also hope this worked for you. If you encounter any issues while following the tutorial, just share them in the comment box, so that we can work to make it better.

Have A Look At Our Top Rated WooCommerce Plugins ThemeHigh

Nabeel Aslam is a technical writer and content marketer for Flyingloop. He writes product marketing contents and blogs for WordPress and other web related services since he joined the team in 2018.

Leave a Comment