Ruby

capistranoでRailsアプリケーションをdeployする

More than 5 years have passed since last update.

注意!!こちらの記事はCapistrano2系の内容です!!


capistranoのインストール

Gemfileに下記を追記し、bundle installを実行する。

# Gemfile

group :deployment do
gem 'capistrano'
gem 'capistrano-ext' # 環境毎に設定を変更するためのgem
gem 'capistrano_colors' # capistrano実行時に色をつけるためのgem
gem 'capistrano_rsync_with_remote_cache' # deploy時にrsyncを使うためのgem
end

$ bundle install


初期化

gemをインストールすると、capifyコマンドが使用できるようになる。

capifyコマンドを実行すると、設定ファイルが作成される。

$ bundle exec capify .

[add] writing './Capfile'
[add] writing './config/deploy.rb'
[done] capified!


設定ファイル編集


基本的な設定項目

公式ドキュメントはこちら。

https://github.com/capistrano/capistrano/wiki/2.x-Significant-Configuration-Variables


アプリ名の定義

set :application, 'myapp'


deploy先のパスを設定

set :deploy_to, '/path/to/app'


hostの設定

下記は一つのサーバを一辺にまとめて定義する方法。

server "localhost", :app, :web, :db, :primary => true

細かくroleを指定することも可能。

role :web, 'localhost'

role :web, '127.0.0.1'
role :db, 'localhost', :master => true

roleを指定してtaskの実行が可能。

# webのroleに設定されているhostに対して実行

task :sample, :roles => :web do
# ...
end

# dbのroleでなおかつ、masterオプションがtrueのhostに対して実行
task :sample2, :roles => :db, :only => {:master => true} do
# ...
end


stageの設定

deploy先の環境の定義。

capistranoコマンドを実行するとき、下記の環境を指定できるようになる。

set :stages, %w(production staging)

set :default_stage, "staging"

$ bundle exec cap staging deploy

$ bundle exec cap production deploy


バージョン管理の設定

下記では、subversionを指定しているが、gitやmercurialなども指定できる。

set :repository,  "Repository URL"

set :scm, :subversion
set :scm_username, "username"
set :scm_password, "password"


デプロイユーザーの設定

set :user, 'app'

set :password, 'password'
ssh_options[:keys] = "~/.ssh/id_rsa"
set :use_sudo, false


世代管理数

set :keep_releases, 5


deploy方法の設定

下記では、普段よくつかうrsync_with_remote_cacheを設定している。

この他に、copyやremote_cacheなども指定できる。

set :deploy_via, :rsync_with_remote_cache

# deploy方法がrsync_with_remote_cacheのため、
# rsync時に除外するファイルや、オプションを設定する
set :copy_exclude, %W(
.svn
**/.svn
.git
**/.git
.bundle/
.gitignore
.ruby-version
)

set :rsync_options, '-rtlvz --delete --delete-excluded ' +
copy_exclude.map{|e| "--exclude='#{e}'"}.join(' ')


環境依存の設定を分割する

applicationやdeploy_toなどは、環境によって設定する値が変わってくる。

そのため、共通して使用できる設定は、config/deploy.rbに書き、環境に依存する設定は別ファイルに逃がしてあげる必要がある。

この仕組は、capistrano-extというgemがすでに用意してくれている。


環境依存ファイルを作成する

staging用の設定であれば、config/deploy/staging.rbに、

production用の設定であれば、config/deploy/production.rbを作成するだけである。


config/deploy/production.rb

set :application, "production app name"

set :deploy_to, '/path/to/app/production'
set :rails_env, 'production'
role :web, 'web01'
role :web, 'web02'
role :db, 'db01'


config/deploy/staging.rb

set :application, "staging app name"

set :deploy_to, '/path/to/app/staging'
set :rails_env, 'staging'
server "localhost", :app, :web, :db, :primary => true


最終的な設定ファイル

https://gist.github.com/tanihiro/6060400

https://gist.github.com/tanihiro/6060419

いくつかtaskを追加して、unicornやdatabaseの設定ファイルをsharedに逃がして、シンボリックリンクを設定したり、capistrano経由でunicornのプロセス操作を行えるようにした。


deployのセットアップ

設定ファイルの記入が完了したら、デプロイの前準備をする。

capistranoが予め提供してくれている、deploy:setupコマンドを実行し、デプロイに必要なディレクトリをリモートの環境に作成しする。

$ bundle exec cap staging deploy:setup

deploy:setupコマンドを実行すると、下記のようなディレクトリが deploy_to で指定したディレクトリに作成される。

.

├── releases
└── shared
├── log
├── pids
└── system


ディレクトリ構成の概要

capistranoによるdeployは世代管理ができるディレクトリ構成になっている。


releases

releasesディレクトリに、ソースコードが格納される。

この時、deployの度にtimestampでディレクトリが作成される。

─── releases

├── 20130723024019
├── 20130723024428
└── 20130723024445


shared

releasesに作成された各ディレクトリで共通で使用したいファイルなどを格納するためのディレクトリ。

例えば、logなどはreleasesの各ディレクトリに書きだされてしまうと、デプロイの度に、ログファイルが別れてしまうので、実態ファイルはsharedに設置し、releases内のログファイルはshared内のログファイルにシンボリックリンクを設定する。

/deploy_to/releases/20130723024445/log -> /deploy_to/shared/log


current

releases内に作成された最新のディレクトリに、シンボリックリンクを設定し、currentとして設置する。

WEBサーバからは、このcurrentをDocumentRootに設定する。

そうすることで、別のreleasesのディレクトリにシンボリックリンクを切り替えれば、簡単に前のバージョンのソースコードに戻したりすることが可能になる。

/deploy_to/current -> /deploy_to/releases/20130723024445


deployを実行

deployの実行は、deployコマンドを実行する。

この時の挙動は、 deploy_via で指定したモードによって異なる。

$ bundle exec cap staging deploy


rsync_with_remote_cacheの場合

rsync_with_remote_cacheの挙動は簡単にまとめると、下記の順序で処理が進む。


  1. ローカルの.rsync-cacheディレクトリに、ソースをチェックアウト、もしくは最新のソースの反映

  2. ローカルの.rsync-cacheディレクトリから、リモートのshared/cached-copy/ディレクトリにrsyncで転送

  3. リモートのサーバ内で、cached-copyディレクトリから、releasesにrsyncで転送

  4. ソース転送後の処理を実行(shared内でbundle installなど)

  5. 最新のreleaseディレクトリに、currentのシンボリックリンクを切り替える

※ ローカルのどこにソースをチェックアウトするかは、deploy.rbの local_cache を設定することで変更することができる。


copyの場合

deploy実行の度に、バージョン管理から最新のソースをエクスポートし、圧縮させてからscpで転送→解凍を実行する。


remote_cacheの場合

rsync_with_remote_cacheは、ローカルでチェックアウトし、rsyncでshared/cached-copyに転送していたのに対し、remote_cacheはリモートで直接shared/cached-copyにチェックアウトを実行する。

以降は、アップデートを行うため、毎回チェックアウトする手間が省ける。


その他のcapistranoコマンド

下記を参照。

https://github.com/capistrano/capistrano/wiki/Capistrano-Tasks