Deploy Ruby on Rails with Capistrano and Ubuntu Server

September 3, 2023

Step 1: Install Dependencies

sudo apt-get update && sudo apt-get -y upgrade
sudo apt install zlib1g-dev build-essential libssl-dev libreadline-dev
sudo apt install libyaml-dev libsqlite3-dev sqlite3 libxml2-dev
sudo apt install libxslt1-dev libcurl4-openssl-dev
sudo apt install software-properties-common libffi-dev nodejs
sudo apt install git
sudo apt install nginx
sudo apt install autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm-dev libsqlite3-dev

Step 2: Setup Rbenv

git clone https://github.com/rbenv/rbenv.git ~/.rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(~/.rbenv/bin/rbenv init - bash)"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
source ~/.bashrc
rbenv init
type rbenv

Step 3: Setup Ruby Build

git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build

Step 4: Install Ruby

RUBY_CONFIGURE_OPTS=--disable-install-doc rbenv install 2.7.5
rbenv rehash
echo "gem: --no-document" > ~/.gemrc

Step 5-8: Install Rails, Puma, Bundler, Node-JS and Yarn

gem install rails
gem install puma
gem install bundler -v 2.1.4 --no-ri --no-rdoc
sudo apt-get install nodejs
sudo apt install yarn

Step 9: Install MySQL Dependencies

sudo apt-get install libmysqlclient-dev
gem install mysql2 -v '0.5.0' --source 'https://rubygems.org/'

Step 10: SSH Configuration

ssh-keygen -o -t rsa -b 4096 -C "[email protected]"
chmod o+x $HOME

Step 11: Capistrano Setup

group :development do
  gem "web-console"
  gem 'capistrano'
  gem 'capistrano-rails'
  gem 'capistrano-rbenv'
  gem 'capistrano-sidekiq'
  gem 'capistrano-bundler'
  gem 'capistrano3-puma'
end

Step 12-13: Initialize Capistrano and Database Config

cd root-project
cap install STAGES=production

Step 14-16: Service Configuration

Configure Puma service, set secret key, and setup Nginx for your application.

Puma Service Configuration

[Unit]
Description=Puma HTTP Server for timetable (production)
After=network.target

[Service]
Type=simple
User=ubuntu
WorkingDirectory=/home/ubuntu/timetable/current
ExecStart=/home/ubuntu/.rbenv/bin/rbenv exec bundle exec --keep-file-descriptors puma -C /home/ubuntu/timetable/shared/puma.rb
ExecReload=/bin/kill -USR1 $MAINPID
StandardOutput=append:/home/ubuntu/timetable/current/log/puma.access.log
StandardError=append:/home/ubuntu/timetable/current/log/puma.error.log

Restart=always
RestartSec=1

SyslogIdentifier=puma

[Install]
WantedBy=multi-user.target

Nginx Configuration

upstream timetable_app {
  server unix:/home/ubuntu/timetable/shared/tmp/sockets/puma.sock fail_timeout=0;
}

server {
  listen 80;
  server_name _;
  root /home/ubuntu/timetable/current/public;

  location / {
    try_files $uri/index.html $uri @timetable_app;
  }

  location @timetable_app {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://timetable_app;
  }

  error_page 500 502 503 504 /500.html;
  client_max_body_size 4G;
  keepalive_timeout 10;
}
#Ruby #Rails #Capistrano #Ubuntu #Deployment