My public ip : 51.15.204.137 Log in to your new server by ssh, use key/pair or password depending on the service you have chosen
ssh root@51.15.204.137
Now let's create a new user that we call deploy
or whatever you want and add it to the sudo group
adduser deploy # Create a newuser and this password (wasn't afraid to use a complex password)
usermod -aG sudo deploy # Add 'deploy' user to sudo group
exit # Exit ssh sessions with root
Now log in with deploy user but first we can configure access for use key/pair instead of password
ssh-copy-id deploy@51.15.204.137 # Enter your password to use when creating 'deploy' user
ssh deploy@51.15.204.137 # Magic no password asked !!!
The first thing to do is to update the system and install some essential dependencies
sudo apt-get update # Update packages list
sudo apt-get upgrade # Update installed packages
sudo apt install -y git zsh curl jq build-essential tklib zlib1g-dev libssl-dev libffi-dev libxml2 libxml2-dev libxslt1-dev libreadline-dev # Install essential dependencies
sudo apt clean
sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)" # Install oh-my-zsh for shell autocompletion, history and more
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | zsh # Install nvm to easyly manage node version
zsh # To reload shell
nvm install --lts # To install the latest stable version (version is currently 10.16.3)
nvm alias default 10.16.3
Ruby installation with rbenv
rvm implode && sudo rm -rf ~/.rvm # Remove rvm if exist
rm -rf ~/.rbenv # Remove rbenv if exist
git clone https://github.com/rbenv/rbenv.git ~/.rbenv # Install rbenv
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build # Install ruby-build
zsh # To reload config
rbenv # To check command
On some linux versions, the PATH
variable is not automatically updated.
Open the .zshrc
with nano
and add the following to the file
cd
nano .zshrc
export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"
Now re-run
zsh
rbenv
Install the latest version or ruby
rbenv install 2.6.3 # Install ruby
# It's quite long, it can take up to 10min depending on the computers.
rbenv global 2.6.3 # Set version globally
zsh # Reload config
ruby -v # Check ruby version, it must be ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-linux]
gem install rails rake bundler # Install basic gems to manage rails project
Let's now install a POSTGRESQL server or whatever else you want
sudo apt install -y postgresql postgresql-contrib libpq-dev # Installs postgresql and the necessary dependencies
sudo -u postgres psql --command "CREATE ROLE `whoami` LOGIN createdb;" # Create a postgresql user named 'deploy'
Finally, we will install nginx and its module for passenger so that our ruby application can be interpreted and publicly available.
sudo apt-get install nginx # Install nginx server
# 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
sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger stretch main > /etc/apt/sources.list.d/passenger.list'
sudo apt-get update
sudo apt-get install -y libnginx-mod-http-passenger
sudo service nginx restart
You can read more (here for nginx and passenger integration)[https://www.phusionpassenger.com/library/walkthroughs/deploy/ruby/ownserver/nginx/oss/stretch/install_passenger.html]
sudo nano /etc/sudoers
so that capistrano can restart nginx, in sudoers file add the following line at the end
ALL ALL=NOPASSWD: /etc/init.d/nginx restart
The last thing we need to do before configuring capistrano and nginx is to create deployment directories
mkdir -p /home/deploy/www/rails-react-demo # Create directories
exit # To return on local machine
go to Gemfile
and add fallowing to development group
group :development do
# Use Capistrano for deployment
gem "capistrano", "~> 3.10", require: false
gem "capistrano-rails", "~> 1.4", require: false
gem 'capistrano-rbenv', '~> 2.1'
gem 'capistrano-nvm', require: false
gem 'capistrano-yarn'
gem 'capistrano3-nginx', '~> 2.0'
gem 'capistrano-passenger'
end
Then run
bundle install
bundle exec cap install
Go to Capfile
and uncomment following
require "capistrano/rbenv"
require "capistrano/bundler"
We will come back to uncomment capistrano/rails/migrations
after the first deployment.
Go to config/deploy/production.rb
and add this line. Of course, change the server address with yours
server "51.15.204.137", user: "deploy", roles: %w{app db web}
Now go to config/deploy.rb
and update it like this
# config valid for current version and patch releases of Capistrano
lock "~> 3.11.0"
set :application, "rails-react-demo"
set :repo_url, "git@github.com:Eth3rnit3/rails-react-demo.git"
# Default deploy_to directory is /var/www/my_app_name
set :deploy_to, "/home/deploy/www/rails-react-demo"
# 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.6.3'
# Nvm/Node.JS
set :nvm_type, :user # or :system, depends on your nvm setup
set :nvm_node, 'v10.16.3'
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
end
To avoid errors during the first deployment, we will reconnect to the server and go to the deployment directory, we will create a shared directory (used by capistrano) and a config directory inside. In the config directory, we will add the two linked files. master.key and database.yml which are as follows but which you can modify if necessary
ssh deploy@51.15.204.137
cd www/rails-react-demo
mkdir -p shared/config
touch shared/config/master.key
touch shared/config/database.yml
# Make RAILS_ENV
cd
nano .zshrc # add export RAILS_ENV=production or type it everytime
master.key
is generated by rails, copy locally and paste on server
database.yml
is quite personal, it's up to you to set it up as needed. However, if you have followed this tutorial, here is the configuration adapted
default: &default
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
production:
<<: *default
database: rails_react_demo_production
username: deploy
Next create nginx log files
mkdir /home/deploy/www/rails-react-demo/logs
touch /home/deploy/www/rails-react-demo/logs/access.log
touch /home/deploy/www/rails-react-demo/logs/errors.log
Return locally We are now able to run the first deploy
cap production deploy
Normally you should not get an error message but if this is the case capistrano is rather explicit, you should be able to fix it simply
Let's go back to the server and go to the deploy directory
cd /home/deploy/www/rails-react-demo/current
rails db:create
rails db:migrate
# Created database 'rails_react_demo_production'
Add yarn too for react build script
npm install -g yarn
It's time to configure nginx to forward our application to the public. First, let's launch the application with passenger
cd /home/deploy/www/rails-react-demo/current
passenger start --daemonize --address 127.0.0.1 --port 3000
And configure nginx
cd /etc/nginx/sites-available
sudo nano rails-react-demo
Add the following config
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
root /home/deploy/www/rails-react-demo/current/public;
index index.html;
server_name 51.15.204.137;
access_log /home/deploy/www/rails-react-demo/logs/access.log;
error_log /home/deploy/www/rails-react-demo/logs/errors.log;
server_name localhost;
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 Host $http_host;
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 /index.html;
}
}
Active the new config
cd /etc/nginx/sites-enabled
sudo rm default
sudo ln -s /etc/nginx/sites-available/rails-react-demo ./rails-react-demo
sudo service nginx restart
Return to Capfile
, uncomment and add
require "capistrano/rails/migrations"
require "capistrano/nvm"
require 'capistrano/yarn'
require "capistrano/nginx"
require "capistrano/passenger"
And finally the final deployment!, just run
cap production deploy
You can follow the deployment until the end. if all is well, past (which should be the case) you can go to the ip address of the server, and you will see your application appear. Open the console and click on the fetch button, you should see an answer appear in the console. If you receive an error 500, it is probably because rails has been badly restarted.
Don't panic, do the following
ssh deploy@51.15.204.137
cd /home/deploy/www/rails-react-demo/current
passenger stop && passenger start --daemonize --address 127.0.0.1 --port 3000
sudo /etc/init.d/nginx restart
Refresh your browser and click again on the fetch button
You can add this command shortcut as an alias into .zshrc
file
alias restart-app="cd /home/deploy/www/rails-react-demo/current && passenger stop && passenger start --daemonize --address 127.0.0.1 --port 3000 && sudo /etc/init.d/nginx restart && cd"