rails3のアプリ作成しcapistranoを使って配備するまでのチュートリアルを示す。

railsアプリを作る

$ rails new myapp
create
create  README
create  Rakefile
= 途中省略 =
run  bundle install
= 途中省略 =
Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.

アプリを起動する

$ cd myapp

※javascriptのライブラリ不足でエラーになるので以下を追記
・「Gemfile」を編集

gem 'execjs'
gem 'therubyracer'

gem 'capistrano' ←コメントイン

・Gemfileで指定したライブラリをインストール

$ bundle install

capistranoでの配信に対応させる(capify)

$ bundle exec capify .
[add] writing './Capfile'
[add] writing './config/deploy.rb'
[done] capified!

生成されたファイルの確認

・「Capfile」を参照する

load 'deploy' if respond_to?(:namespace) # cap2 differentiator

# Uncomment if you are using Rails' asset pipeline
# load 'deploy/assets'

Dir['vendor/gems/*/recipes/*.rb','vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) }

load 'config/deploy' # remove this line to skip loading any of the default tasks

・「./config/deploy.rb」を参照する

set :application, "set your application name here"
set :repository,  "set your repository location here"

set :scm, :subversion
# Or: `accurev`, `bzr`, `cvs`, `darcs`, `git`, `mercurial`, `perforce`, `subversion` or `none`

role :web, "your web-server here"                          # Your HTTP server, Apache/etc
role :app, "your app-server here"                          # This may be the same as your `Web` server
role :db,  "your primary db-server here", :primary => true # This is where Rails migrations will run
role :db,  "your slave db-server here"

# if you're still using the script/reaper helper you will need
# these http://github.com/rails/irs_process_scripts

# If you are using Passenger mod_rails uncomment this:
# namespace :deploy do
#   task :start do ; end
#   task :stop do ; end
#   task :restart, :roles => :app, :except => { :no_release => true } do
#     run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}"
#   end
# end

配信コマンドを確認する

$ bundle exec cap -T
cap deploy               # Deploys your project.
cap deploy:check         # Test deployment dependencies.
cap deploy:cleanup       # Clean up old releases.
cap deploy:cold          # Deploys and starts a `cold' application.
cap deploy:migrate       # Run the migrate rake task.
cap deploy:migrations    # Deploy and run pending migrations.
cap deploy:pending       # Displays the commits since your last deploy.
cap deploy:pending:diff  # Displays the `diff' since your last deploy.
cap deploy:restart       # Blank task exists as a hook into which to install ...
cap deploy:rollback      # Rolls back to a previous version and restarts.
cap deploy:rollback:code # Rolls back to the previously deployed version.
cap deploy:setup         # Prepares one or more servers for deployment.
cap deploy:start         # Blank task exists as a hook into which to install ...
cap deploy:stop          # Blank task exists as a hook into which to install ...
cap deploy:symlink       # Updates the symlink to the most recently deployed ...
cap deploy:update        # Copies your project and updates the symlink.
cap deploy:update_code   # Copies your project to the remote servers.
cap deploy:upload        # Copy files to the currently deployed version.
cap deploy:web:disable   # Present a maintenance page to visitors.
cap deploy:web:enable    # Makes the application web-accessible again.
cap invoke               # Invoke a single command on the remote servers.
cap shell                # Begin an interactive Capistrano session.

Some tasks were not listed, either because they have no description,
or because they are only used internally by other tasks. To see all
tasks, type `cap -vT'.

Extended help may be available for these tasks.
Type `cap -e taskname' to view it.

作成したアプリケーションをgitにコミットする

$ git init
Initialized empty Git repository in /home/mikamitakeshi/myapp/.git/
$ git add --all
$ git commit -a -m "initial commit"
[master (root-commit) cb1a4bb] initial commit
39 files changed, 1219 insertions(+), 0 deletions(-)
create mode 100644 .gitignore
create mode 100644 Capfile
= 途中省略 =
create mode 100644 vendor/plugins/.gitkeep

配信用の定義を記載する

・「./config/deploy.rb」を編集する

set :application, "myapp"
set :repository,  "※作業ディレクトリを指定(例:/home/user01/myapp)※"

set :scm, :git
# Or: `accurev`, `bzr`, `cvs`, `darcs`, `git`, `mercurial`, `perforce`, `subversion` or `none`

role :web, "127.0.0.1"                          # Your HTTP server, Apache/etc
role :app, "127.0.0.1"                          # This may be the same as your `Web` server
role :db,  "127.0.0.1", :primary => true # This is where Rails migrations will run
role :db,  "127.0.0.1"

実際に配信する(cap)

・配信先ディレクトリを作っておく←配信先サーバで実行

$ sudo mkdir -p /u/apps/myapp/releases /u/apps/myapp/shared/log /u/apps/myapp/shared/pids
$ sudo chown -R ※配信ユーザ(例:user01)※:※配信ユーザグループ(例:user01)※ /u/apps/myapp

・配信する

$ bundle exec cap deploy
* executing `deploy'
* executing `deploy:update'
** transaction: start
* executing `deploy:update_code'
executing locally: "git ls-remote /home/user01/myapp HEAD"
command finished in 36ms
* executing "git clone -q /home/user01/myapp /u/apps/myapp/releases/20120124035234 && cd /u/apps/myapp/releases/20120124035234 && git checkout -q -b deploy cb1a4bb38001c03d6face683f6607df53a3151a1 && (echo cb1a4bb38001c03d6face683f6607df53a3151a1 > /u/apps/myapp/releases/20120124035234/REVISION)"
servers: ["127.0.0.1"]
Password:
[127.0.0.1] executing command
command finished in 535ms
* executing `deploy:finalize_update'
* executing "chmod -R g+w /u/apps/myapp/releases/20120124035234"
servers: ["127.0.0.1"]
[127.0.0.1] executing command
command finished in 377ms
* executing "rm -rf /u/apps/myapp/releases/20120124035234/log /u/apps/myapp/releases/20120124035234/public/system /u/apps/myapp/releases/20120124035234/tmp/pids &&\\\n      mkdir -p /u/apps/myapp/releases/20120124035234/public &&\\\n      mkdir -p /u/apps/myapp/releases/20120124035234/tmp &&\\\n      ln -s /u/apps/myapp/shared/log /u/apps/myapp/releases/20120124035234/log &&\\\n      ln -s /u/apps/myapp/shared/system /u/apps/myapp/releases/20120124035234/public/system &&\\\n      ln -s /u/apps/myapp/shared/pids /u/apps/myapp/releases/20120124035234/tmp/pids"
servers: ["127.0.0.1"]
[127.0.0.1] executing command
command finished in 393ms
* executing "find /u/apps/myapp/releases/20120124035234/public/images /u/apps/myapp/releases/20120124035234/public/stylesheets /u/apps/myapp/releases/20120124035234/public/javascripts -exec touch -t 201201240352.38 {} ';'; true"
servers: ["127.0.0.1"]
[127.0.0.1] executing command
*** [err :: 127.0.0.1] find:
*** [err :: 127.0.0.1] `/u/apps/myapp/releases/20120124035234/public/images'
*** [err :: 127.0.0.1] : そのようなファイルやディレクトリはありません
*** [err :: 127.0.0.1]
*** [err :: 127.0.0.1] find:
*** [err :: 127.0.0.1] `/u/apps/myapp/releases/20120124035234/public/stylesheets'
*** [err :: 127.0.0.1] : そのようなファイルやディレクトリはありません
*** [err :: 127.0.0.1]
*** [err :: 127.0.0.1] find:
*** [err :: 127.0.0.1] `/u/apps/myapp/releases/20120124035234/public/javascripts'
*** [err :: 127.0.0.1] : そのようなファイルやディレクトリはありません
*** [err :: 127.0.0.1]
command finished in 389ms
* executing `deploy:symlink'
* executing "rm -f /u/apps/myapp/current && ln -s /u/apps/myapp/releases/20120124035234 /u/apps/myapp/current"
servers: ["127.0.0.1"]
[127.0.0.1] executing command
command finished in 420ms
** transaction: commit
* executing `deploy:restart'

■おまけ:配信のカスタマイズ

multistageに対応させる

→staging用/produnction用など配信定義を分けたい場合

・config/deploy.rb ← 共通の定義
・config/deploy/production.rb ← production用の定義
・config/deploy/staging.rb ← staging用の定義

production.rb/staging.rbに環境固有の定義を記載し、
deploy.rbには共通の定義を記載する。

production/stagingには以下のコマンドで配備を行う。
$ bundle exec cap production deploy ← productionの場合
$ bundle exec cap staging deploy ← stagingの場合

配信前後の処理を追加する

・「config/deploy.rb」を編集する

# namespace :deploy do
#   task :start do ; end  ←★サーバ開始の処理を記載する
#   task :stop do ; end  ←★サーバ停止の処理を記載する
#   task :restart, :roles => :app, :except => { :no_release => true } do
#     run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}"
#   end
# end

※配信前後にサーバの再起動、asset::precompileを追加した例

after "deploy:update_code", "deploy:pipeline_precompile"

namespace :deploy do
task :start, :roles => :app, :except => { :no_release => true } do
run "sudo /etc/init.d/#{application} start"
end
task :stop, :roles => :app, :except => { :no_release => true } do
run "sudo /etc/init.d/#{application} stop"
end
task :graceful_stop, :roles => :app, :except => { :no_release => true } do
run "sudo /etc/init.d/#{application} graceful_stop"
end
task :reload, :roles => :app, :except => { :no_release => true } do
run "sudo /etc/init.d/#{application} reload"
end
task :restart, :roles => :app, :except => { :no_release => true } do
stop
start
end

task :pipeline_precompile do
run "cd #{release_path}; RAILS_ENV=#{rails_env} bundle exec rake assets:precompile"
end
end