Skip to content

Instantly share code, notes, and snippets.

@joshteng
Last active August 29, 2015 13:57
Show Gist options
  • Save joshteng/9896037 to your computer and use it in GitHub Desktop.
Save joshteng/9896037 to your computer and use it in GitHub Desktop.
Manual Server Set Up + Deploy With Capistrano (not working yet)

All the executables and code to deploy a rails app to a VPS
if you need more explaination, check out: http://www.talkingquickly.co.uk/2014/01/deploying-rails-apps-to-a-vps-with-capistrano-v3/

ON THE SERVER

Step 1: Create a deployer user

sudo adduser deployer
sudo adduser deployer sudo
su deployer

Step 2: Install SSH-copy-id if not yet

brew install ssh-copy-id

Step 3: Use SSH Keys for SSH access

ssh-copy-id deployer@IPADDRESS

Step 4: Exit root user and log in as deployer

exit
exit
ssh deployer@IPADDRESS

##Step 5: Install needed system libraries and Postgresql

sudo apt-get update
sudo apt-get install git-core curl zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt-dev libcurl4-openssl-dev python-software-properties libpq-dev postgresql postgresql-contrib

##Step 6: Install ruby

cd
git clone git://github.com/sstephenson/rbenv.git .rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
exec $SHELL

git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bashrc
exec $SHELL

rbenv install 2.1.0
rbenv global 2.1.0
rbenv rehash

##Step 7: Install Bundler

echo "gem: --no-ri --no-rdoc" > ~/.gemrc
gem install bundler

##Step 8: Install Node.js for Rails asset pipeline

sudo add-apt-repository ppa:chris-lea/node.js
sudo apt-get update
sudo apt-get install nodejs

Step 9: Install Nginx on server

sudo apt-get install nginx

##Step 10: Add github as known host

https://help.github.com/articles/generating-ssh-keys

##Step 11: Set up database user and write the username and password somewhere (we need it later!)

sudo su - postgres
createuser --pwprompt
exit
username: deploy
password: anything

BACK TO DEVELOPMENT

????? Step 12: Set up config/database.yml to use the user set up?????

production:
  adapter: postgresql
  encoding: unicode
  database: database_name
  pool: 16
  username: database_username
  password: database_password

##Step 13: Set up Capistrano

Gemfile

gem 'capistrano', '~> 3.1.0'
gem 'capistrano-bundler', '~> 1.1.2'
gem 'capistrano-rails', '~> 1.1.1'

# Add this if you're using rbenv
gem 'capistrano-rbenv', github: "capistrano/rbenv"

Run shell commands

bundle --binstubs
cap install STAGES=production

Add this to Capfile

require 'capistrano/bundler'
require 'capistrano/rails'

Modify config/deploy.rb

set :application, 'myapp'
set :repo_url, '[email protected]:excid3/myapp.git'

set :deploy_to, '/home/deploy/myapp'

set :linked_files, %w{config/database.yml}
set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}

namespace :deploy do

  desc 'Restart application'
  task :restart do
    on roles(:app), in: :sequence, wait: 5 do
      execute :touch, release_path.join('tmp/restart.txt')
    end
  end

  after :finishing, 'deploy:cleanup'
end

Modify config/deploy/production.rb

set :stage, :production

# Replace 127.0.0.1 with your server's IP address!
server '127.0.0.1', user: 'deploy', roles: %w{web app}

Step 14: Use unicorn.rb

Gemfile

gem 'unicorn'

install unicorn

bundle install

config/unicorn.rb

root = "/home/deployer/app_name"
working_directory root
pid "#{root}/tmp/pids/unicorn.pid"
stderr_path "#{root}/log/unicorn.log"
stdout_path "#{root}/log/unicorn.log"

listen "/tmp/unicorn.blog.sock"
worker_processes 2
timeout 30

Step 15: Create config/nginx.conf

upstream unicorn {
  server unix:/tmp/unicorn.blog.sock fail_timeout=0;
}

server {
  listen 80 default deferred;
  # server_name example.com;
  root /home/deployer/apps/app_name/current/public;

  location ^~ /assets/ {
    gzip_static on;
    expires max;
    add_header Cache-Control 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;
}

Step 16: Create config/unicorn_init.sh

#!/bin/sh
### BEGIN INIT INFO
# Provides:          unicorn
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Manage unicorn server
# Description:       Start, stop, restart unicorn server for a specific application.
### END INIT INFO
set -e

# Feel free to change any of the following variables for your app:
TIMEOUT=${TIMEOUT-60}
APP_ROOT=/home/deployer/apps/blog/current
PID=$APP_ROOT/tmp/pids/unicorn.pid
CMD="cd $APP_ROOT; bundle exec unicorn -D -c $APP_ROOT/config/unicorn.rb -E production"
AS_USER=deployer
set -u

OLD_PIN="$PID.oldbin"

sig () {
  test -s "$PID" && kill -$1 `cat $PID`
}

oldsig () {
  test -s $OLD_PIN && kill -$1 `cat $OLD_PIN`
}

run () {
  if [ "$(id -un)" = "$AS_USER" ]; then
    eval $1
  else
    su -c "$1" - $AS_USER
  fi
}

case "$1" in
start)
  sig 0 && echo >&2 "Already running" && exit 0
  run "$CMD"
  ;;
stop)
  sig QUIT && exit 0
  echo >&2 "Not running"
  ;;
force-stop)
  sig TERM && exit 0
  echo >&2 "Not running"
  ;;
restart|reload)
  sig HUP && echo reloaded OK && exit 0
  echo >&2 "Couldn't reload, starting '$CMD' instead"
  run "$CMD"
  ;;
upgrade)
  if sig USR2 && sleep 2 && sig 0 && oldsig QUIT
  then
    n=$TIMEOUT
    while test -s $OLD_PIN && test $n -ge 0
    do
      printf '.' && sleep 1 && n=$(( $n - 1 ))
    done
    echo

    if test $n -lt 0 && test -s $OLD_PIN
    then
      echo >&2 "$OLD_PIN still exists after $TIMEOUT seconds"
      exit 1
    fi
    exit 0
  fi
  echo >&2 "Couldn't upgrade, starting '$CMD' instead"
  run "$CMD"
  ;;
reopen-logs)
  sig USR1
  ;;
*)
  echo >&2 "Usage: $0 <start|stop|restart|upgrade|force-stop|reopen-logs>"
  exit 1
  ;;
esac

Step 17: Make nginx.conf executable

chmod +x config/unicorn_init.sh

Step 18: Git ignore files (.gitignore)

config/database.yml

Step 19: Commit and Deploy

git add .
git commit -am "deploy"
cap production deploy

???? Step 20: Symlink configuration files (should be part of recipe) ????

  • database.yml
  • application.yml
  • unicorn_init.sh
  • nginx.conf

Step 21: Install upstart

Step 22: Install monit

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment