Step 1.

Setup you hostinger server
  • SSH into the remote server : ssh root@<hostinger_ip_address>
  • Create user: sudo adduser <newusername>
  • Grant administrative rights: sudo usermod -aG sudo <newusername>
Configure access:
  • sudo visudo
  • And add this line : <newusername> ALL=(ALL) NOPASSWD:ALL

Switch user: su - <newusername>

Generate SSH Key and add to github

ssh-keygen -t rsa -b 4096 : once its generated add the public key to github

Make a directory where rails app will be deployed
  • mkdir -p /path/to/parent_directory/sub_directory
  • example in our case: mkdir -p /home/<newusername>/<application_name>
  • Change the ownership: sudo chown -R <newusername>:group /home/<newusername>/<application_name>
Install prerequisite:
  • sudo apt-get update
  • sudo apt-get install -y curl git-core nodejs yarn build-essential libpq-dev
Install rvm
  • \curl -sSL https://get.rvm.io | bash -s stable --ruby
  • source ~/.rvm/scripts/rvm
  • rvm use 3.1.2 --default
Install postgresql
  • sudo apt update
  • sudo apt install postgresql postgresql-contrib
  • sudo systemctl start postgresql
  • sudo systemctl enable postgresql
Create user in postgresql
  • sudo -u postgres psql
  • create user: CREATE USER username WITH PASSWORD 'password';
  • Alter the user: ALTER USER username WITH SUPERUSER CREATEDB CREATEROLE REPLICATION BYPASSRLS;

Note: If you have other database providers(example: AWS RDS) you can skip he postgresql installation

Step 2

Generate SSH Key and add to hostinger server
Execute below on your local machine
  • ssh-keygen -t ed25519 -C your_email@example.com
  • ssh-copy-id -i ~/.ssh/id_ed25519.pub <hostinger_newusername>@<hostinger_ip_address>
Configure your rails app:
  • Add below gems inside development group of your gem file

group :development do
  gem 'capistrano'
  gem 'capistrano3-puma'
  gem 'capistrano-rails', require: false
  gem 'capistrano-bundler', require: false
  gem 'capistrano-rvm'
end

  • bundle install
  • bundle exec cap install
  • modify your Capfile

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/rails/assets'
require 'capistrano/puma'
require "capistrano/rails/migrations"
Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }

  • modify your deploy.rb file

lock "~> 3.18.0"
set :application, '<application_name>'
set :repo_url, '<git ssh url, example: git@github.com:ak-need/test-rails.git>' # Edit this to match your repository
set :branch, :main
set :deploy_to, '/home/<newusername>/<application_name>'
set :pty, true
set :linked_files,  %w{ config/boot.rb config/master.key config/credentials.yml.enc config/database.yml config/storage.yml }
append :linked_dirs,  'log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', '.bundle', 'public/system', 'public/uploads', 'public/images', 'public/documents'
set :config_files,  %w(database.yml)
set :keep_releases, 5
set :rvm_type, :user
set :rvm_ruby_version, 'ruby-3.1.2' # Edit this if you are using MRI Ruby
set :puma_rackup, -> { File.join(current_path, 'config.ru') }
set :puma_state, "#{shared_path}/tmp/pids/puma.state"
set :puma_pid, "#{shared_path}/tmp/pids/puma.pid"
set :puma_bind, "unix://#{shared_path}/tmp/sockets/puma.sock"    #accept array for multi-bind
set :puma_conf, "#{shared_path}/puma.rb"
set :puma_access_log, "#{shared_path}/log/puma_error.log"
set :puma_error_log, "#{shared_path}/log/puma_access.log"
set :puma_role, :app
set :puma_env, fetch(:rack_env, fetch(:rails_env, 'production'))
set :puma_threads, [0, 8]
set :puma_workers, 0
set :puma_worker_timeout, nil
set :puma_init_active_record, true
set :puma_preload_app, false
namespace :deploy do
  after :restart, :clear_cache do
    on roles(:web), in: :groups, limit: 3, wait: 10 do
    end
  end
end

  • modify your config/deploy/production.rb file

set :user,            'deploy'
set :pty,             true
set :use_sudo,        true
set :stage,           :production
set :deploy_via,      :remote_cache
set :deploy_to,       "/home/<newusername>/<application_name>"
set :ssh_options,     { forward_agent: true, user: '<newusername>' }
set :branch,          'main' # Default branch is master
server '82.112.235.108', user: '<newusername>', roles: %w{web app db}, primary: true
namespace :deploy do
  desc 'Restart application'
  task :restart do
    on roles(:app), in: :sequence, wait: 5 do
      execute "sudo service nginx restart"
    end
  end
  after :finishing, 'deploy:restart'
  after :finishing, 'deploy:cleanup'
end

  • Copy linked_files from you local machine to hostinger server

###### Move to your rails app directory if you are not there 
scp config/database.yml <newusername>@<hostinger_ip_address>:/home/<newusername>/shared/config/
example: scp config/database.yml test@83.111.215.208:/home/test/shared/config/

Finaly

bundle exec cap production deploy

Your application should be deployed but now configure nginx with passenger
  • sudo apt-get update
  • sudo apt-get install -y libnginx-mod-http-passenger
  • sudo nano /etc/nginx/sites-available/default and paste the below

server {
  listen 80 default_server;
  listen [::]:80 default_server;
  server_name <domain name or ip address>;
  root /home/<newusername>/<application_name>/current/public;
  passenger_enabled on;
  passenger_app_env production;
  # Add index.php to the list if you are using PHP
  index index.html index.htm index.nginx-debian.html;
  server_name _;
  location / {
    try_files $uri @app;
  }
  location @app {
      passenger_enabled on;
      passenger_base_uri /;
      passenger_app_root /home/<newusername>/<application_name>/current;
      passenger_document_root /home/<newusername>/<application_name>/current/public;
      passenger_ruby /home/<newusername>/.rvm/rubies/ruby-3.1.2/bin/ruby;
      passenger_app_env production;
  } 
}

  • Test nginx sudo nginx -t
  • Finally restart the nginx: sudo systemctl restart nginx

Comments(0)