Ruby on Rails のデプロイ自動化でよく使われる capistrano と、そのGUI環境の webistrano ですが、もちろん Ruby on Rails 以外にも使うことができます。 今回は ZendFramework のデプロイをしてみようと思います。
ゴール
ここでは、以下のような状況のもと本番環境にデプロイする準備をします。
- github 上の master ブランチにあるソースコードをデプロイする。
- リポジトリでは ZendFramework 本体やログディレクトリなどは管理していない。
インストール
capistrano は ruby 製です。まずは ruby がないと始まらないので最初に ruby をインストールします。1.8.6 以上が必要です。それから webistrano は DB として mysql を利用しますので、こちらもインストールしておきます。ruby と mysql のインストールは他に詳しい記事がいっぱいあるので割愛。
ruby と mysql が準備できたら capistrano と webistrano をインストールします。といっても webistrano をインストールするときに一緒に capistrano も入るので webistrano をインストールするだけです。
$ cd path/to/webistrano
// git から clone
$ git clone git@github.com:peritor/webistrano.git webistrano
// 設定ファイルをコピー
$ cd webistrano/config
$ cp webistrano_config.rb.sample webistrano_config.rb
$ cp database.yml.sample database.yml
ディレクトリ構成を見てわかるかもしれませんが webistrano は Ruby on Rails 2 で動いています。まず最初にデータベースの設定 database.yml
を編集します。
// ユーザー名やパスワード、DB名を環境に合わせて修正
production:
adapter: mysql
database: webistrano_production
username: root
password:
socket: /tmp/mysql.sock
ここで指定したデータベース名をあらかじめ作っておきます(この例では webistrano_production
という名前のDB)。
他に webistrano_config.rb
という設定ファイルもありますがこっちはメール関連の設定で、デプロイ時や例外発生時などに飛ばすメールのFromやSMTPサーバーの設定などを記述します。特にいじらなくても動くことは動くので面倒くさければ飛ばしてもいいと思います。
それから webistrano で DB のマイグレーションをする時に rake コマンドを使うのですが webistrano が必要としている rake のバージョンが多少古いので Gemfile
に rake のバージョンを指定してあげます。あと bundler のバージョンも指定されてますが、僕はこれも消しました。
source "http://rubygems.org"
gem 'bundler'
gem "rails", "2.3.11"
gem "mysql"
gem "erubis"
# rake の 0.8.7 を指定してあげる。
# 指定がなければ最新バージョンが入ってしまい rake db:migrate の時にエラーが起こる
gem "rake", "0.8.7"
gem "syntax", "1.0.0"
gem "capistrano", "2.6.0"
gem "open4", "0.9.3"
gem "exception_notification", "2.3.3.0"
group :test do
gem "mocha", "0.9.8"
end
あと、僕の環境では git clone してきたソースをそのまま使うとエラーが出るページがあって lib/webistrano/deployer.rb
を以下のように書き換えています。
# 25行目あたり
# if(@deployment.task && !@deployment.new_record?)
if(!@deployment.new_record? && @deployment.task)
そしてインストールの続き。
// 必要な gem をインストール
$ bundle install --path vendor/bundle
// DB のマイグレーション
$ RAILS_ENV=production bundle exec rake db:migrate
// webistrano 起動
$ ruby script/server -d -p 3000 -e production
ここまでやると http://localhost:3000/
で webistrano が起動しています。アクセスしてこんな画面が出ればインストール成功。
デフォルトのユーザーとして admin ユーザーがいます。パスワードも admin です。
鍵の登録
webistrano を実行しているサーバーで git clone して、そのソースファイルをデプロイ先のサーバーへ送信することになるので webistrano を実行しているユーザーの鍵を github に登録します。
# webistrano 実行ユーザーで作業する
$ ssh-keygen -t rsa # パスフレーズは空で。Enterキー連打で鍵生成
$ cat ~/.ssh/id_rsa.pub
id_rsa.pub
の内容をgithubに登録します。念のため登録がうまくいってるかどうか確認。
$ ssh git@github.com
Hi tkengo! Youve successfully authenticated, but Github does not provide shell access.
また webistrano からデプロイ先のサーバーへ SSH でログインしていろいろと作業するので、デプロイ先のサーバーへも鍵を登録します。
# webistrano 実行ユーザーで作業する
$ scp ~/.ssh/id_rsa.pub deployer@zendframework.tkengo.com:/home/deployer
$ ssh deployer@zendframework.tkengo.com
$ cat ~/id_rsa.pub >> ~/.ssh/authorized_keys
$ chmod 600 ~/.ssh/authorized_keys
念のためパスワードなしでログイン出来るかどうか確認。
# webistrano 実行ユーザーで
$ ssh deployer@zendframework.tkengo.com
webistranoの設定
まずはログインします。ログインID、パスワード、共に admin でログインできます。これから webistrano で以下の設定をしていきます。
- プロジェクト デプロイするプロジェクト。
- ホスト デプロイ先のサーバー。デプロイ先のサーバーが複数台あればその分だけ登録しますし、開発環境などにもデプロイしたければその分も登録します。
- レシピ デプロイ時に webistrano に実行させるコマンドの定義。
- ステージ デプロイの環境のようなもので、例えば
本番環境
本番テスト環境
開発環境
など、環境毎にステージを作ります。
プロジェクトの作成
左メニューの Projects の New project から新しいプロジェクトを作ります。
Project Type には Pure File を選びます。
ホストの作成
左メニューの Hosts の New host から新しくデプロイ先のホストを作ります。
デプロイ先サーバーのIPアドレスまたはホスト名を入力します。
レシピの作成
左メニューの Recipes の New recipe から新しいレシピを作ります。
capistrano にはデフォルトでいろいろなタスクがありますが、足りない処理があったり余分な処理があったりするので、そういうものを上書きしてあげる必要があります。ここでは Zendframework 用デプロイのレシピと SSH ログイン用のレシピを作成します。
各タスクが何をしているかというのは webistrano をインストールしたフォルダの vendor/bundle/ruby/[バージョン]/gems/capistrano-[バージョン]/lib/capistrano/recipes/deploy.rb
というソースに書かれています。
Zendframework 用のレシピについて
namespace :deploy do
# 不要なタスクを全部空にして何もしないようにします
task :start do ; end
task :stop do ; end
task :restart do; end
# リポジトリで管理していないファイルやディレクトリなどに
# シンボリックリンクを貼るコマンドを実行
task :update_config, :roles => :app do
require 'pathname'
# data/cache と data/logs というディレクトリにシンボリックリンクをはる
%w(cache logs).each do |dir|
src = "#{shared_path}/system/data/#{dir}"
dest = "#{latest_release}/data/#{dir}"
run "ln -s #{src} #{dest}"
end
# Zendframework 本体にシンボリックリンクをはる
src = "#{shared_path}/system/Zend"
dest = "#{latest_release}/application/library/Zend"
run "ln -s #{src} #{dest}"
# リポジトリで管理していないパスワード系のファイルにシンボリックリンクをはる
%w(password.php key.php).each do |file|
src = "#{shared_path}/system/#{file}"
dest = "#{latest_release}/#{file}"
run "ln -s #{src} #{dest}"
end
# 必要に応じて他にもファイルがあればコピーまたはシンボリックリンクをはるコマンドを実行
end
# デプロイの最後に上で定義した update_config を実行する
after 'deploy:finalize_update', 'deploy:update_config'
end
webistrano(capistrano) を使ってデプロイするとここでも書いていますが、特徴的なディレクトリになります。各ディレクトリの説明はリンク先のエントリを読んでください(^_^;)
current/
release/
shared/
リポジトリを clone したものを release
以下に配置したとすると、リポジトリ管理されていないファイルなどは release
以下には含まれません。なので、そういったファイルは shared
以下に配置して webistrano がデプロイ完了した後に shared
のファイルやディレクトリをコピーもしくはシンボリックリンクを貼らないといけません。このレシピはそういったコマンドを実行しています。
レシピは ruby で記述します。shared
以下のパスは shared_path 、最新の release
以下のパスは latest_release という変数で参照できます。
SSH ログイン用のレシピについて
# webistrano 実行ユーザーの鍵を指定します
ssh_options[:keys] = %w(/home/[webistrano実行ユーザー名]/.ssh/id_rsa)
webistrano 実行ユーザーとデプロイ先のユーザーとが一致していない場合うまくいかなかったのですが、このレシピを指定するとうまくいきました。
ステージの作成
さっき作ったプロジェクトが左メニューに追加されていて、そこに New state というリンクが表示されているので、クリックして新しくステージを作ります。
Alert these emails on deploy はデプロイ時にメールを飛ばす場合にメールアドレスを入力します。不要な場合は空のままで大丈夫です。
プロジェクトの設定
プロジェクトの設定をしていきます。
プロジェクトをクリックすると以下のような設定画面が表示されます。
- application デプロイするアプリケーション名。わかりやすいものであればなんでも良いです。
- deploy_to アプリケーションをデプロイするパス。デプロイ先サーバーのパスを入力します。
- deploy_via デプロイ方法を指定します。ここで指定している
:copy
は webistrano のサーバーに git clone して、それを tar で固めて SFTP でデプロイ先のサーバーに送信します。他にも:remote_cache
や:checkout
などがあります。 - user デプロイ先サーバーへ SSH でログインする時のユーザー名を指定します。
- password SSH のパスワードを指定します。
- scm 今回は github からのデプロイなので
git
を指定します。 - repository リポジトリです。github のリポジトリを指定します。
ステージの設定
ステージの設定をしていきます。
ステージをクリックすると以下のような設定画面が表示されます。
ステージは親のプロジェクトの設定を引き継ぎます。ステージ特有の設定を持たせたい場合は Stage specific configuration にある New configuration から新しく設定を作ります。
それから先に作った Zendframework 用のレシピと SSH ログイン用のレシピを Used recipes の Manage stage recipes から選択しておきます。これで、このステージで Zendframework 用のレシピが使われるようになります。
あとは、デプロイ先のホストも登録しておきます。Deployed hosts の Add host からデプロイする先のホストを追加します。Role はとりあえず app で Host にデプロイ先のホストを入れます。ホストはステージ毎に設定できるので、先にも言いましたが例えば 本番環境
と 開発環境
をステージ毎に分けれます。
デプロイ
ようやく設定が完了しました。あとはデプロイリンクをぽちっとクリックするだけです。
Start deployment をクリック!あとはログが流れるのを観察して成功を待つだけ!
終わりに
とりあえず Zendframework をデプロイすることを目標に進めてきましたが、なにも Zendframework じゃなくても CakePHP なんかでも、同じ様に CakePHP 用のレシピを作ればデプロイできますし、素の PHP だってできます。PHP 以外の言語ももちろん。
それから、デプロイ以外にも rollback という機能もあって、直前にデプロイしたものに戻すこともできます。他にもいっぱいタスクがありますが、ちょっとここじゃ紹介しきれないのでまた機会があれば。一応、タスクの一覧は cap -T
とコマンドラインからたたけば見ることができます。
webistrano 使うとデプロイがすごい楽です。使ってみませんか?