Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save artiwarahd/66593c6b1bb68cd6041cfb0892688bfb to your computer and use it in GitHub Desktop.
Save artiwarahd/66593c6b1bb68cd6041cfb0892688bfb to your computer and use it in GitHub Desktop.
### DigitalOcean Ubuntu 18.04 x64 + Rails 5 + Nginx + Unicorn + PostgreSQL9.6 + Capistrano 3
SSH into Root
$ ssh root@123.123.123.123
Change Root Password
$ passwd
Add Deploy User
$ adduser deployer
$ sudo chown deployer:deployer /var/www/
Update Sudo Privileges
$ visudo
username ALL=(ALL:ALL) ALL
Generate public key
$ su - deployer
$ mkdir ~/.ssh
$ cd ~/.ssh
$ ssh-keygen
Add authorized_keys
$ nano authorized_keys # then add your key
Install Curl
$ sudo apt-get update
$ sudo apt-get install curl
Install RVM
$ curl -L get.rvm.io | bash -s stable
$ source /etc/profile.d/rvm.sh
$ usermod -a -G rvm deployer
$ rvm requirements
$ rvm install 2.4.2
$ rvm use 2.4.2 --default
$ rvm rubygems current
In case of cannot install old ruby version
$ cd /usr/local/src/
$ sudo wget https://www.openssl.org/source/openssl-1.1.1s.tar.gz
$ sudo tar -xf openssl-1.1.1s.tar.gz
$ cd openssl-1.1.1s
$ sudo ./config --prefix=/usr/local/ssl --openssldir=/usr/local/ssl shared zlib
$ sudo make
$ sudo make install
$ sudo rmdir certs
$ sudo ln -sf /etc/ssl/certs/ certs
$ rvm install 2.4.2 --with-openssl-dir=/usr/local/ssl
Install PostgreSQL
visit: https://www.postgresql.org/download/linux/ubuntu/
or: https://askubuntu.com/questions/1052079/unable-to-install-postgresql-9-6-in-ubuntu-18-04
$ sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-pgdg main" >> /etc/apt/sources.list.d/pgdg.list'
$ wget -q https://www.postgresql.org/media/keys/ACCC4CF8.asc -O - | sudo apt-key add -
$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get install postgresql-9.6 postgresql-server-dev-9.6
$ sudo apt-get install libpq-dev
$ gem install pg -v 1.2.3 -- --with-pg-config=/usr/bin/pg_config
Create Postgres User
$ sudo -u postgres psql
create user deployer with password 'xxxxxxxx';
alter role deployer superuser createrole createdb replication;
create database MYAPP_DATABASE owner deployer;
Install GIT
$ sudo apt-get install git-core
Install Bundler
$ gem install bundler
Install Imagemagick
$ sudo apt-get install imagemagick libmagickwand-dev
$ sudo apt install redis
Setup Nginx
$ sudo apt-get install nginx
$ nginx -h
$ cat /etc/init.d/nginx
$ /etc/init.d/nginx -h
$ sudo service nginx start
$ sudo vim /etc/nginx/sites-enabled/default
upstream unicorn {
server unix:/var/www/rails/MYAPP/current/tmp/sockets/unicorn.myapp.sock fail_timeout=0;
}
server {
listen 80 default deferred;
# server_name example.com;
root /var/www/rails/MYAPP/current/public;
location ^~ /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
location ~ ^/(robots.txt|sitemap.xml.gz)/ {
root /var/www/rails/MYAPP/current/public;
}
try_files $uri/index.html $uri @unicorn;
location @unicorn {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://unicorn;
}
error_page 500 502 503 504 /500.html;
client_max_body_size 4G;
keepalive_timeout 10;
}
Exit from ssh
$ exit
Add Unicorn
$ vim Gemfile
gem "capistrano", "3.10"
gem 'capistrano-rvm'
gem 'capistrano-bundler'
gem 'capistrano-rails'
gem 'unicorn'
gem 'capistrano3-unicorn'
Update Unicorn Config
$ vim config/unicorn/production.rb
root = "/var/www/rails/MY_APP/current"
working_directory root
pid "#{root}/tmp/pids/unicorn.pid"
stderr_path "#{root}/log/unicorn_error.log"
stdout_path "#{root}/log/unicorn_output.log"
# worker_processes Integer(ENV['WEB_CONCURRENCY'])
worker_processes 2
timeout 10
preload_app true
listen "#{root}/tmp/sockets/unicorn.myapp.sock", backlog: 64
before_fork do |server, worker|
Signal.trap 'TERM' do
puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
Process.kill 'QUIT', Process.pid
end
defined?(ActiveRecord::Base) and
ActiveRecord::Base.connection.disconnect!
end
after_fork do |server, worker|
Signal.trap 'TERM' do
puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to send QUIT'
end
defined?(ActiveRecord::Base) and
ActiveRecord::Base.establish_connection
end
# Force the bundler gemfile environment variable to
# reference the capistrano "current" symlink
before_exec do |_|
ENV['BUNDLE_GEMFILE'] = File.join(root, 'Gemfile')
end
Install Capistrano
$ bundle exec cap install
Update Capistrano Capfile
$ vim Capfile
# Load DSL and set up stages
require "capistrano/setup"
# Include default deployment tasks
require "capistrano/deploy"
# Load the SCM plugin appropriate to your project:
#
# require "capistrano/scm/hg"
# install_plugin Capistrano::SCM::Hg
# or
# require "capistrano/scm/svn"
# install_plugin Capistrano::SCM::Svn
# or
require "capistrano/scm/git"
install_plugin Capistrano::SCM::Git
# Include tasks from other gems included in your Gemfile
#
# For documentation on these, see for example:
#
# https://github.com/capistrano/rvm
# https://github.com/capistrano/rbenv
# https://github.com/capistrano/chruby
# https://github.com/capistrano/bundler
# https://github.com/capistrano/rails
# https://github.com/capistrano/passenger
#
require "capistrano/rvm"
# require "capistrano/rbenv"
# require "capistrano/chruby"
require "capistrano/bundler"
# require "capistrano/rails/assets"
require "capistrano/rails/migrations"
# require "capistrano/passenger"
require 'capistrano3/unicorn'
# Load custom tasks from `lib/capistrano/tasks` if you have any defined
Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }
Update Capistrano Deploy Config
$ vim config/deploy.rb
# config valid for current version and patch releases of Capistrano
# lock "~> 3.10.0"
set :application, "MYAPP"
set :repo_url, "git@bitbucket.org:dev-team-alpha/MYAPP.git"
# Default branch is :master
# ask :branch, `git rev-parse --abbrev-ref HEAD`.chomp
# Default deploy_to directory is /var/www/my_app_name
set :deploy_to, "/var/www/rails/MYAPP"
# Default value for :format is :airbrussh.
# set :format, :airbrussh
# You can configure the Airbrussh format using :format_options.
# These are the defaults.
# set :format_options, command_output: true, log_file: "log/capistrano.log", color: :auto, truncate: :auto
# Default value for :pty is false
# set :pty, true
# Default value for :linked_files is []
append :linked_files, "config/database.yml", "config/application.yml"
# Default value for linked_dirs is []
append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "public/system"
# Default value for default_env is {}
# set :default_env, { path: "/opt/ruby/bin:$PATH" }
# Default value for local_user is ENV['USER']
# set :local_user, -> { `git config user.name`.chomp }
# Default value for keep_releases is 5
set :keep_releases, 5
# Uncomment the following to require manually verifying the host key before first deploy.
# set :ssh_options, verify_host_key: :secure
namespace :deploy do
desc 'Restart application'
task :restart do
on roles(:web), in: :sequence, wait: 5 do
execute :touch, release_path.join('tmp/restart.txt')
end
end
end
after 'deploy:restart', 'unicorn:duplicate'
Update Production Deploy Config
$ vim config/deploy/production.rb
set :port, 22
set :user, 'ubuntu'
set :deploy_via, :remote_cache
set :use_sudo, false
server '123.123.123.123', port: fetch(:port), user: fetch(:user), roles: %w{app db web}
set :stage, :production
set :rails_env, :production
set :unicorn_env, :production
set :unicorn_rack_env, 'production'
set :branch, "master"
Add SSH Key to DigitalOcean
$ cat ~/.ssh/id_rsa.pub | ssh -p 22 username@123.123.123.123 'cat >> ~/.ssh/authorized_keys'
Say Hi to Github
# follow the steps in this guide if receive permission denied(public key)
# https://help.github.com/articles/error-permission-denied-publickey
$ ssh github@github.com
Check Deployment (Commit and Push)
$ cap production deploy:check
Deploy & restart unicorn
$ cap production deploy
$ bundle exec cap production unicorn:stop
$ bundle exec cap production unicorn:start
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment