はじめまして。 最近結婚しましたVASILYのエンジニア庄司です。 VASILY では最近、アジャイル開発を取り入れ始めました。 アジャイル開発では開発工程の早い段階でのデプロイ自動化が推奨されています。
・開発の終盤でデプロイスクリプトを書くより安全・安心
・自動化されていることで細かく頻繁なアップデートが可能
そこで、Rails定番で利用実績の多いCapistranoを選択しました。 今回はRailsアプリケーションの自動デプロイツールCapistranoを紹介します。
Capistranoとは
Railsアプリケーションに特化したデプロイ自動化ツールです。 以下のような特徴があります。
・Rubyで書かれたRails定番のデプロイツール ・デプロイ/リストアがコマンド一発
・デプロイのバージョン管理
・複数サーバにインストール可能。
・配信先サーバには何もインストールしない。
・配信中コケてもデプロイ実行前の状態にロールバックしてくれる。
・git,subversion,Mercurialなどのリポジトリのデータをデプロイできる。
・Rails以外のデプロイなどにも利用可能 (その分設定は複雑になる)
今回テストした環境
・CentOS release 5.5 (Final)
・ruby 1.9.2p180
・Rails 3.0.5
・git 1.7.4
インストール方法 Gemfileに以下を追記し、bundle install を実行
#development環境にのみインストール group :development do gem 'capistrano' end
Capistranoを採用の前提条件 ・git,subversion等のSCMでソースコード管理されていること ・デプロイ先サーバにsshでログインができること
デプロイの流れ 以下の流れで、gitから最新のソースコードを取得し、Railsアプリケーションを起動します。
初回の準備
$ cd /home/vasily/test_app #Rails Application Root $ capify . #capistranoのconfigファイル作成 $ vim config/deploy.rb #下記参照 $ cap deploy:setup #デプロイ先サーバに必要なフォルダを作る(初回デプロイ時のみ)
デプロイ
$ cap deploy #gitから取得 + Railsアプリケーション再起動 $ cap deploy:migrate #DBスキーマに変更があった場合のみ、本番DBへのmigrationを実行
deploy.rb
require "bundler/capistrano" #(1) set :application, "test_app" #(2) set :scm, :git #(3) set :repository, "ssh://..." #(4) set :scm_user, “vasily” #(5) set :deploy_to, "/home/vasily/test_app" #(6) set :deploy_via, :copy #(7) set :user, "vasily" #(8) set :use_sudo, true #(9) default_run_options[:pty] = true #(10) role :web, "www.exampl.com" #(11) role :app, "www.exampl.com" #(12) role :db, "www.exampl.com", :primary => true #(13) namespace :deploy do #(14) 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
(1) Rails3用の設定 デプロイ後、bundle installを実行してくれます。
(2) Railsアプリケーション名
(3) リポジトリ管理ツール VASILYではgitを使用しています。
(4) リポジトリのURI
(5) リポジトリユーザ名
(6) デプロイ先ディレクトリ
(7) プッシュ式デプロイ デフォルトでは、デプロイ先サーバでgit cloneを行いますが、VASILYのgitリポジトリは社内ネットワーク内のサーバにあるため、本番環境からgit pullすることができません。 set :deploy_via, :copy と設定することで、git cloneしたソースコードをtarで固めてscpで配布します。 また、プッシュ式デプロイにすることで、デプロイ先サーバにgitをインストールする必要がなくなります。
(8) デプロイ先サーバにsshするユーザ
(9) sudoの使用を許可するか
(10) pseudo-ttyを利用するかどうか デフォルトはfalse。 リモートでsudoコマンドを実行する際に、「sudo: no tty present and no askpass program specified」というエラーが出る場合、これを設定するといいです。
(11) webサーバ 複数指定する場合は、以下のように設定します。(11), (12)も同様です。 role :web, "web01.exampl.com", “web02.exampl.com”, ...
(12) デプロイ先Railsアプリケーションサーバ ほとんどの場合webサーバと同じ
(13) migrateを実行するサーバ DBサーバそのものではなく、rake db:migrate を実行するサーバ
(14) Railsアプリケーション再起動の設定 デフォルトではコメントアウトされていますが、Passengerを使っている場合はこのコメントを外せばいいです。
その他のcapistranoタスク cap -T でタスクを確認できます。
以下に代表的なタスクをまとめます
cap deploy:cold #ソースコード配布 + migration + Railsアプリケーション起動 cap deploy:start #Railsアプリケーション起動 cap deploy:stop #Railsアプリケーション停止 cap deploy:restart #Railsアプリケーション再起動 cap deploy:rollaback #前回のdeploy前の状態にロールバック + Railsアプリケーション再起動 cap deploy:cleanup #デプロイ先の古いソースコードを最新版から5世代分(デフォルト)残して削除
デプロイ先のディレクトリ Capistranoでデプロイした先のサーバでは、バージョン管理の都合上、通常のRailsアプリケーションのディレクトリ構成とは違います。
・releases バージョンごとのRailsアプリケーションのコードです。
・current releases以下のいずれかのディレクトリのシンボリックリンク。通常は最新版を指します。
・shared Railsアプリケーション内の一部のうち、ログファイルやbundlerで管理するgemパッケージなどデプロイの度に更新してほしくないファイルが置かれます。
実際のディレクトリ構成
/home/vasily/test_app/ |-- current -> /home/vasily/test_app/releases/20110603132533 |-- releases | |-- 20110530110205 .... | |-- 20110530121423 .... | |-- 20110530122100 | | |-- app | | |-- config | | |-- db | | |-- doc | | |-- lib | | |-- log -> /home/vasily/test_app/shared/log | | |-- public | | | --- system -> /home/vasily/test_app/shared/system | | |-- script | | |-- spec | | |-- tmp | | | --- pids -> /home/vasily/test_app/shared/pids | | --- vendor | --- 20110603132533 | |-- app | |-- config | |-- db | |-- doc | |-- lib | |-- log -> /home/vasily/test_app/shared/log | |-- public | | --- system -> /home/vasily/test_app/shared/system | |-- script | |-- spec | |-- tmp | | --- pids -> /home/vasily/test_app/shared/pids | --- vendor --- shared |-- bundle | --- ruby |-- log |-- pids --- system
その他の機能 ・メンテナンスページへの切り替え
・独自タスクの設定
・Railsアプリケーション以外での利用 など、便利な機能がありますが、これらはまた今後のエントリーで。
それでは!