さくらVPSにまっさらな状態からRuby2.1.0+Rails4.2.1+nginx+unicorn+capistranoの環境を構築したのでやんわり手順を書いた。


さくらVPSを借りてみたのでRailsを動かしてついでに手元のローカル環境で作ったアプリをデプロイ出来るようにしてみました。
完全に初心者なので、細かい所は分かってませんが初心者目線で出来ればと思います。
コピペしていけば構築出来るというサルでき方式を目指して書きました。

##登場人物
ruby - rubyこれは知ってた。javaの親戚みたいなやつ
rbenv - rubyのバージョンを選べるようにする便利なやつ
rails - rubyを使ったサイトの構築を簡単に行うやつ
nginx - サーバーソフト？だと思う。こいつがいれば複数のrailsプロジェクトを１つのサーバーで動かせる？っぽい。よくわからないけど人気っぽい
unicorn - `rails s`で動くやつはWebrickって言うんだけど、それが重いからこれを使うらしい
capistrano - デプロイするやつ。多分gitをサーバー側にcloneしてついでに色々セットアップしてくれている。

##さくらVPSの初期化
管理コンソールからOSインストール>標準OSインストール
しばらく待つと使えるようになる。
`Updating RPMS on system`と表示されても処理は進んでいるので焦らずに待つ（10分くらい）

##定数
以下の解説では下記のように読み替えてください
>${IP_ADDRESS} -> 000:00:00:000 (さくらVPSのIP）

>${APP_NAME} -> testApp （アプリ名）

>${GIT_URL} -> githubのリポジトリのurl。この解説ではrailsにcapistranoのセットアップをする直前にリポジトリを作りますが、タイミングが微妙なので先に作っていてもいいです。


##ログイン
Terminal.appを開いて、さくらVPSに繋げる
最初に鍵を作るか聞かれるのでyes
さっきのパスワードでログインする

```:terminal.app
$ ssh root@${IP_ADDRESS}
```

サーバーを初期化したりするとIPが一緒なのに鍵が合わなくて怒られるので、その際は鍵を消した後ログイン

```:terminal.app
$ ssh-keygen -R ${IP_ADDRESS}
```

##rbenvをインストール(server側)

```:さくらVPS
$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
```

##環境設定の末行に追記する(server側)

```~/.bash_profile
export PATH="~/.rbenv/bin:$PATH"
eval "$(rbenv init -)"
```

~/.bash_profileを再読み込み(server側)

```:さくらVPS
$ source ~/.bash_profile
```

##ruby_buildをインストール(server側)

```:さくらVPS
$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
```

```:さくらVPS
$ sudo ~/.rbenv/plugins/ruby-build/install.sh
```

##ssl(server側)

```:さくらVPS
$ sudo yum -y install openssl-devel
```

##rubyをインストールする(server側)
少しかかります
readline-develを入れないとエラーが出るようになったのでいれる

```:さくらVPS
$ yum install -y readline-devel
```

```:さくらVPS
$ rbenv install 2.2.2
$ rbenv rehash
$ rbenv global 2.2.2
```

##bundlerのインストール

```:さくらVPS
$ gem install bundler
```

##SQlite3をインストール(server側)
インストールするか聞かれるので「y」

```:さくらVPS
$ yum install sqlite-devel
```

##nodejsをインストール(server側)

```:さくらVPS
$ yum install nodejs npm --enablerepo=epel
```

##nginxをインストール(server側)

```:さくらVPS
$ sudo yum install -y nginx
```


##nginxのセットアップ(server側)

```nginx:/etc/nginx/conf.d/local.conf
upstream unicorn {
  server unix:/var/www/app/${APP_NAME}/current/tmp/unicorn.sock;
}

server {
  listen 80 default_server;

  access_log /var/log/nginx/sample_access.log;
  error_log /var/log/nginx/sample_error.log;

  root /var/www/app/${APP_NAME}/current;

  client_max_body_size 100m;
  error_page 404 /404.html;
  error_page 500 502 503 504 /500.html;
  try_files $uri/index.html $uri @unicorn;

  location @unicorn {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_pass http://unicorn;
  }
}
```

--

以下はクライアント(Mac側)

##railsプロジェクト作る

```:terminal.app
$ rails new sample
```

##プロジェクト修正

```rb:Gemfile
gem 'rb-readline'
gem 'unicorn'
gem 'capistrano'
gem 'capistrano-rails'
gem 'capistrano-bundler'
gem 'capistrano-rbenv', github: "capistrano/rbenv"

```

```:terminal.app
$ bundle install --path ./vendor/bundle
```

サブドメイン設定。
やってもやらなくてもいい。やるとdomain.com/${APP_NAME}/がルートになる。
名前の前の`/`わすれ注意

```rb:config.ru
# This file is used by Rack-based servers to start the application.
RAILS_RELATIVE_URL_ROOT="/${APP_NAME}"
require ::File.expand_path('../config/environment',  __FILE__)
if RAILS_RELATIVE_URL_ROOT then
        map RAILS_RELATIVE_URL_ROOT do
                run Rails.application
        end
else
        run Rails.application
end

```


##unicornのセットアップ

```rb:./config/unicorn.rb（新規作成）
# -*- coding: utf-8 -*-
worker_processes 2

listen  Dir.pwd + '/tmp/unicorn.sock'
pid     Dir.pwd + '/tmp/unicorn.pid'

log = Dir.pwd + '/log/unicorn.log'
stderr_path File.expand_path('log/unicorn.log', ENV['RAILS_ROOT'])
stdout_path File.expand_path('log/unicorn.log', ENV['RAILS_ROOT'])

preload_app true
GC.respond_to?(:copy_on_write_friendly=) and GC.copy_on_write_friendly = true

before_fork do |server, worker|
defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!

old_pid = "#{ server.config[:pid] }.oldbin"
unless old_pid == server.pid
  begin
   sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
   Process.kill :QUIT, File.read(old_pid).to_i
   rescue Errno::ENOENT, Errno::ESRCH
  end
end
end

after_fork do |server, worker|
    defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
end
```

スクリプト用ディレクトリを作る

```:terminal.app
$ mkdir script
```


```sh:script/unicorn
#!/bin/bash

set -e

TIMEOUT=${TIMEOUT-60}
APP_ROOT=$PWD
PID="$APP_ROOT/tmp/unicorn.pid"
#RAILS_ENV=production
RAILS_ENV=development
CMD="bundle exec unicorn -D -c $APP_ROOT/config/unicorn.rb -E $RAILS_ENV"
action="$1"
set -u

old_pid="$PID.oldbin"

cd $APP_ROOT || exit 1

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

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

case $action in
start)
    sig 0 && echo >&2 "Already running" && exit 0
    $CMD
    ;;
stop)
    sig QUIT && rm -f ${PID} && 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"
    $CMD
    ;;
upgrade)
    if sig USR2 && sleep 2 && sig 0 && oldsig QUIT
    then
        n=$TIMEOUT
        while test -s $old_pid && test $n -ge 0
        do
            printf '.' && sleep 1 && n=$(( $n - 1 ))
        done
        echo

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

権限を付与

```:terminal.app
$ sudo chmod 755 ./script/unicorn
```

##git
githubなどにrailsアプリ全体をpushする。
この後設定するcapistranoでそのgitのurlを使う。
また、デプロイの際はこのリポジトリにpushしたあとにデプロイする

##capistrano

```:terminal.app
$ cap install
```

```rb:Capfile
require 'capistrano/setup'

require 'capistrano/deploy'

require 'capistrano/rbenv'
set :rbenv_type, :user
set :rbenv_ruby, '2.1.0'
require 'capistrano/bundler'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'

Dir.glob('lib/capistrano/tasks/*.cap').each { |r| import r }
```

修正箇所３箇所

```config/deploy.rb
lock '3.4.0'

set :application, '${APP_NAME}'
set :repo_url, '${GIT_URL}'

set :branch, 'master'
set :deploy_to, '/var/www/app/${APP_NAME}'
set :scm, :git
set :log_level, :debug
set :pty, true

set :bundle_binstubs, nil
set :linked_dirs, %w{log tmp/pids tmp/cache tmp/sockets bundle public/system public/assets}
set :default_env, { path: "/usr/local/rbenv/shims:/usr/local/rbenv/bin:$PATH" }
set :keep_releases, 5

namespace :deploy do
  after :finishing, 'deploy:cleanup'
end
```

```config/deploy/development.rb
set :stage, :development
role :app, %w{root@${IP_ADDRESS}}
role :web, %w{root@${IP_ADDRESS}}
role :db, %w{root@${IP_ADDRESS}}

server '${IP_ADDRESS}',
user: 'root',
roles: %w{web app db},
ssh_options: {
 auth_methods: %w(password),
 password: '********'
}

```

`githubへpushして上記のconfig/deploy.rbを対応させる`


##デプロイ
少しかかる
```:terminal.app
$ cap development deploy
```

##サーバー起動

```:さくらVPS
$ cd /var/www/app/${APP_NAME}/current
$ ./script/unicorn start
$ sudo service nginx start
```

#付録
覚えておくと捗るコマンド

`ps aux | grep ${process_name}`
${process_name}が含まれるプロセスを表示。

`kill process_id`
さっきので取得したprocess_idを入れると殺せる

`cd`
階層の移動

`vim ${filename}`
エディタ。iとesc>ZZさえ出来ればOK

`ls`
現階層のファイル一覧表示

`pwd`
現階層までのパスを表示。かわいい


#それでも出来ない

scale使おう