Skip to content

Instantly share code, notes, and snippets.

@fongfan999
Last active May 4, 2017 13:35
Show Gist options
  • Save fongfan999/da5272fd3912b68da9eee996c6e30b22 to your computer and use it in GitHub Desktop.
Save fongfan999/da5272fd3912b68da9eee996c6e30b22 to your computer and use it in GitHub Desktop.

Initial Server Setup

  1. Root Login: ssh root@SERVER_IP_ADDRESS
  2. Create a New User: adduser deploy
  3. Root Privileges: gpasswd -a deploy sudo
  4. Add Public Key Authentication:
  • Login to new user: su - deploy
  • Add Public Key to New Remote User
    mkdir .ssh
    chmod 700 .ssh
    nano .ssh/authorized_keys # insert your public key by pasting it into the editor.
    chmod 600 .ssh/authorized_keys
    exit
  1. Configure SSH Daemon
# $root
nano /etc/ssh/sshd_config
PermitRootLogin no # disable root login through SSH 
  1. Reload SSH: service ssh restart

Deployment

sudo apt-get update

  1. Installing Nginx: sudo apt-get install curl git-core nginx -y
  2. Installing Databases:
sudo apt-get install postgresql postgresql-contrib
# create superuser test_user
sudo -u postgres createuser --superuser test_user
# set user's password
sudo -u postgres psql
\password test_user
# create database
sudo -u postgres createdb --owner test_user test_app_production
  1. Installing RVM and Ruby
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
curl -sSL https://get.rvm.io | bash -s stable
# reload rvm
source ~/.rvm/scripts/rvm
rvm requirements
rvm install 2.4.0
  1. Installing Rails and Bundler gem install rails --no-ri --no-rdoc gem install bundler --no-ri --no-rdoc
  2. Setting up SSH Keys
ssh-keygen -t rsa
cat .ssh/id_rsa.pub # => add this to Github account
  1. Adding Deployment Configurations in the Rails App
# Gemfile

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

$ bundle install && bundle exec cap install

# Capfile

# Load DSL and set up stages
require "capistrano/setup"

# Include default deployment tasks
require "capistrano/deploy"

require "capistrano/scm/git"
install_plugin Capistrano::SCM::Git

require "capistrano/rails"
require "capistrano/rvm"
require "capistrano/puma"

# Load custom tasks from `lib/capistrano/tasks` if you have any defined
Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }
# config/deploy.rb

# Change these
server 'your_server_ip', port: your_port_num, roles: [:web, :app, :db], primary: true

set :repo_url,        '[email protected]:username/appname.git'
set :application,     'appname'
set :user,            'deploy'
set :puma_threads,    [4, 16]
set :puma_workers,    0

# Don't change these unless you know what you're doing
set :pty,             true
set :use_sudo,        false
set :stage,           :production
set :deploy_via,      :remote_cache
set :deploy_to,       "/home/#{fetch(:user)}/apps/#{fetch(:application)}"
set :puma_bind,       "unix://#{shared_path}/tmp/sockets/#{fetch(:application)}-puma.sock"
set :puma_state,      "#{shared_path}/tmp/pids/puma.state"
set :puma_pid,        "#{shared_path}/tmp/pids/puma.pid"
set :puma_access_log, "#{release_path}/log/puma.error.log"
set :puma_error_log,  "#{release_path}/log/puma.access.log"
set :ssh_options,     { forward_agent: true, user: fetch(:user), keys: %w(~/.ssh/id_rsa.pub) }
set :puma_preload_app, true
set :puma_worker_timeout, nil
set :puma_init_active_record, true  # Change to false when not using ActiveRecord

## Defaults:
# set :scm,           :git
# set :branch,        :master
# set :format,        :pretty
# set :log_level,     :debug
# set :keep_releases, 5

## Linked Files & Directories (Default None):
# set :linked_files, %w{config/database.yml}
# set :linked_dirs,  %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}

namespace :puma do
  desc 'Create Directories for Puma Pids and Socket'
  task :make_dirs do
    on roles(:app) do
      execute "mkdir #{shared_path}/tmp/sockets -p"
      execute "mkdir #{shared_path}/tmp/pids -p"
    end
  end

  before :start, :make_dirs
end

namespace :deploy do
  desc "Make sure local git is in sync with remote."
  task :check_revision do
    on roles(:app) do
      unless `git rev-parse HEAD` == `git rev-parse origin/master`
        puts "WARNING: HEAD is not the same as origin/master"
        puts "Run `git push` to sync changes."
        exit
      end
    end
  end

  desc 'Initial Deploy'
  task :initial do
    on roles(:app) do
      before 'deploy:restart', 'puma:start'
      invoke 'deploy'
    end
  end

  desc 'Restart application'
  task :restart do
    on roles(:app), in: :sequence, wait: 5 do
      invoke 'puma:restart'
    end
  end

  before :starting,     :check_revision
  after  :finishing,    :compile_assets
  after  :finishing,    :cleanup
  after  :finishing,    :restart
end

# ps aux | grep puma    # Get puma pid
# kill -s SIGUSR2 pid   # Restart puma
# kill -s SIGTERM pid   # Stop puma
# config/ngix.conf

upstream puma {
  server unix:///home/deploy/apps/appname/shared/tmp/sockets/appname-puma.sock;
}

server {
  listen 80 default_server deferred;
  # server_name example.com;

  root /home/deploy/apps/appname/current/public;
  access_log /home/deploy/apps/appname/current/log/nginx.access.log;
  error_log /home/deploy/apps/appname/current/log/nginx.error.log info;

  location ^~ /assets/ {
    gzip_static on;
    expires max;
    add_header Cache-Control public;
  }

  try_files $uri/index.html $uri @puma;
  location @puma {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;

    proxy_pass http://puma;
  }

  error_page 500 502 503 504 /500.html;
  client_max_body_size 10M;
  keepalive_timeout 10;
}
  1. Deploying your Rails Application
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment