Edited at

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

More than 1 year has passed since last update.

さくらVPSを借りてみたのでRailsを動かしてついでに手元のローカル環境で作ったアプリをデプロイ出来るようにしてみました。

完全に初心者なので、細かい所は分かってませんが初心者目線で出来ればと思います。

コピペしていけば構築出来るというサルでき方式を目指して書きました。


登場人物

ruby - rubyこれは知ってた。javaの親戚みたいなやつ

rbenv - rubyのバージョンを選べるようにする便利なやつ

rails - rubyを使ったサイトの構築を簡単に行うやつ

nginx - サーバーソフト?だと思う。こいつがいれば複数のrailsプロジェクトを1つのサーバーで動かせる?っぽい。よくわからないけど人気っぽい

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側)


/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



プロジェクト修正


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}/がルートになる。

名前の前の/わすれ注意


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のセットアップ


./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



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



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 }


修正箇所3箇所


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使おう