OS : Ubuntu 18.04LTS
Initial Setup with deploy sudouser
Install rbenv-vars
# Dependencies
sudo apt install -y git zsh curl jq build-essential tklib zlib1g-dev libssl-dev libffi-dev libxml2 libxml2-dev libxslt1-dev libreadline-dev
sudo apt clean
# Oh my zsh
sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
# NVM
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | zsh
# Reload shell
zsh
# Install the latest stable version (currently v14.16.0)
nvm install --lts
nvm alias default 14.16.0# Clean RVM et rbenv
rvm implode && sudo rm -rf ~/.rvm
rm -rf ~/.rbenv
# Install rbenv
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
# Install Ruby-build
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-buildUpdate rbenv PATH
cd
nano .zshrc
# Add PATH to zshrc
export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"
# Reload shell
zsh
# Check rbenv
rbenvInstall Ruby and set version globally
# Install ruby
rbenv install 2.7.2
# Set version globally
rbenv global 2.7.2
# Reload shell
zsh
# Check version (ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-linux])
ruby -v
# Install gem for rails project
gem install rails rake bundlerInstall Postgres and dependencies
sudo apt install -y postgresql postgresql-contrib libpq-devCreate deploy user
sudo -u postgres psql --command "CREATE ROLE `whoami` LOGIN createdb;"Install Nginx and passenger module
# Install nginx server
sudo apt-get install nginx
# Install passenger PGP key and HTTPS support for APT
sudo apt-get install -y dirmngr gnupg
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 561F9B9CAC40B2F7
sudo apt-get install -y apt-transport-https ca-certificates
# Add Passenger API repository
sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger bionic main > /etc/apt/sources.list.d/passenger.list'
sudo apt-get update
# Install Passenger + Nginx module
sudo apt-get install -y libnginx-mod-http-passenger
sudo service nginx restartRemove password requirment when restart Nginx for Capistrano.
sudo nano /etc/sudoers
# Add at the end of file
ALL ALL=NOPASSWD: /etc/init.d/nginx restartCreate the main directory
mkdir -p /home/deploy/www/your-app-name
# Create rbenv-vars
cd /home/deploy/www/your-app-name
touch .rbenv-vars
# Add SECRET_KEY_BASE and others EnvCreate config files
mkdir -p shared/config
touch shared/config/master.key
touch shared/config/database.yml
# Set RAILS_ENV
cd
nano .zshrc
# Add at the end
export RAILS_ENV=productionCopy master.key content locally and past on server.
Configure shared/config/database.yml
default: &default
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
production:
<<: *default
database: your_app_name_production
username: deployCreate Nginx log files
mkdir /home/deploy/www/your-app-name/logs
touch /home/deploy/www/your-app-name/logs/access.log
touch /home/deploy/www/your-app-name/logs/errors.logAdd to development group in Gemfile
group :development do
gem 'capistrano', '~> 3.10', require: false
gem 'capistrano3-nginx', '~> 2.0'
gem 'capistrano-nvm', require: false
gem 'capistrano-passenger' #, '>= 0.2.1'
gem 'capistrano-rails', '~> 1.4', require: false
gem 'capistrano-rbenv', '~> 2.1'
gem 'capistrano-yarn'
endThen run
bundle install
bundle exec cap installGo to Capfile and uncomment
require "capistrano/rbenv"
require "capistrano/bundler"Add this in config/deploy/production.rb
# Change with your server IP
server "11.11.111.1", user: "deploy", roles: %w{app db web}Update config/deploy.rb :
# frozen_string_literal: true
# config valid for current version and patch releases of Capistrano
lock '~> 3.16.0'
set :application, 'your-app-name'
set :repo_url, 'git@github.com:USER/your-app-repo.git'
set :branch, 'main'
# Default deploy_to directory is /var/www/my_app_name
set :deploy_to, '/home/deploy/www/your-app-name'
# Default value for :linked_files is []
append :linked_files, 'config/database.yml', 'config/master.key'
# Default value for linked_dirs is []
append :linked_dirs, 'log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'public/system', 'storage'
# Default value for keep_releases is 5
set :keep_releases, 5
# Rbenv
set :rbenv_type, :user # or :system, depends on your rbenv setup
set :rbenv_ruby, '2.7.2'
# Nvm/Node.JS
set :nvm_type, :user # or :system, depends on your nvm setup
set :nvm_node, 'v14.16.0'
set :nvm_map_bins, %w[node npm yarn]
set :yarn_flags, '--silent --no-progress'
# # Passenger
set :passenger_roles, :app
set :passenger_restart_runner, :sequence
set :passenger_restart_wait, 10
set :passenger_restart_limit, 2
set :passenger_restart_with_sudo, false
set :passenger_environment_variables, { RAILS_ENV: 'production' }
set :passenger_restart_command, 'passenger stop && passenger start --daemonize --address 127.0.0.1 --port 3000'
set :passenger_restart_options, -> { "#{deploy_to}/current" }
# Nginx
set :nginx_roles, :web
set :nginx_sudo_paths, []
set :nginx_sudo_tasks, ['nginx:restart']
# Used to build for optimized production
namespace :deploy do
task :yarn_build do
on roles fetch(:yarn_roles) do
within fetch(:yarn_target_path, release_path) do
execute fetch(:yarn_bin), 'install'
execute fetch(:yarn_bin), 'build'
end
end
end
desc 'Restart application'
task :restart do
on roles fetch(:nginx_roles) do
execute :sudo, '/etc/init.d/nginx restart'
end
end
before 'symlink:release', :yarn_build
after :finishing, :restart
endRun the first deploy
cap production deployCreate Database
cd /home/deploy/www/your-app-name/current
rails db:create
rails db:migrateAdd yarn globally for react build script
npm install -g yarn
Launch application with Passenger
cd /home/deploy/www/your-app-name/current
passenger start --daemonize --address 127.0.0.1 --port 3000Configure Nginx
cd /etc/nginx/sites-available
# remove default if first app
sudo rm default
# create server conf for you app
sudo nano your-app-nameUpdate your-app-namefor HTTPS
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
root /home/deploy/www/your-app-name/current/public;
index index.html;
server_name domain.com;
access_log /home/deploy/www/your-app-name/logs/access.log;
error_log /home/deploy/www/your-app-name/logs/errors.log;
# server_name localhost;
passenger_app_root /home/deploy/www/your-app-name;
passenger_enabled on;
passenger_app_env production;
client_max_body_size 20M;
location ~* ^.+\.(jpeg|gif|png|jpg|webp) {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
}
location /api {
# Insert your public app path
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_buffering off;
}
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ /index.html;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = domain.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name domain.com;
server_name localhost;
return 404; # managed by Certbot
}
Active the new config
cd /etc/nginx/sites-enabled
# remove default if first app
sudo rm default
# Link conf file
sudo ln -s /etc/nginx/sites-available/your-app-name /etc/nginx/sites-enabled/
sudo service nginx restartEdit Capfile and uncomment
require "capistrano/rails/migrations"
require "capistrano/nvm"
require 'capistrano/yarn'
require "capistrano/nginx"
require "capistrano/passenger"Final deploy
cap production deploy
Create alias for restart app
nano ~/.zshrc
# add at the end
alias restart-app="cd /home/deploy/www/your-app-name/current && passenger stop && passenger start --daemonize --address 127.0.0.1 --port 3000 && sudo /etc/init.d/nginx restart && cd"
Restart App
restart-app
MAGIE !