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.
Component | Version |
Linux | Ubuntu 18.04.1 |
Ruby | Latest from rvm.io |
Rails | Latest gem package |
Puma | Latest gem package |
Nginx | Latest from APT |
Node.js | Latest from APT |
Postgres | Latest from APT |
Postfix | Latest from APT |
Certbot | Latest 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