肉とビールとパンケーキ by @sotarok

少し大人になった「肉とご飯と甘いもの」

Capistrano + rsync で省エネデプロイ

こんにちは。

タイトルの通りなんですが、Capistrano みんなつかってるよねー。
ってことで独自のデプロイシステムをもってなくてさすがにFTPでUPはしてませんって人は結構使ってるもんだと思ってるんですけど、Capistrano ってなんかデフォルト各サーバで vcs の update 的なことをするか、ローカルにソースツリーを用意してやる場合に使えるのは scp で、なんかエコじゃないよねと言う話で、いちいちソースツリー全部配布されてたら転送量も時間もかかってしょうがないので、まーrsyncがいいんだよね、ということで、そんな時は capistrano_rsync_with_remote_cache (なげえよ) を使えばいいよね!ってお話です。 *1


このご時世なんでも省エネがいいんです。

インストール

gem で適当にインストール。

$ gem install capistrano_rsync_with_remote_cache

今だと2.4.0ってやつが入りました。

使い方

deploy_via が重要なわけだけど、その他ももろもろ揃えておく。多分このツールのすごいところは、scm 的なところは既存のリポジトリの枠でそれを local cache として保持して、deploy_via で、deploy の strategy だけちゃんと切り替えられるところのような気がしている。

set :scm, :git
set :deploy_via, :rsync_with_remote_cache
set :git_enable_submodules, true
set :repository, "."
set :copy_exclude, %w(
    .git
    Capfile
    config/hogeohge.ini
    cache
    app/logs
)
set :rsync_options, '-az --delete --delete-excluded --exclude=.git --exclude=' + copy_exclude.join(' --exclude=')

えーなんかこうですね、 :copy_exclude ってでデフォルトの Capistrano のオプションを指定しつつそれを :rsync_options に指定しちゃうところがオサレなかんじでしょうか?(ここの中身は適当に。)
でなんかこんなことにしておくと、よしなに rsync でremoteにあるディレクトリに差分でアップロードして、そこからrelease_pathにコピーして使ってくれる感じになります。


ちなみに deploy strategy にはデフォルトで :remote_cache っていう似てるっぽいやつがあるんですがこれはこれで全然違うやつで、 deploy -> remote の転送は普通に scm なやつで、remoteにリポジトリのコピーを1つもっておいて、そこからrelease_pathにコピーして使うんですよっていうやつです。

仕組み

超適当ですがこんなかんじの仕組みで動いてます。まぁあまり気合の入った図ではないんですが適当に感じ取ってください。


簡単に言うと、repository "." なので、そのディレクトリをすでに git リポジトリにしておくわけですが(いやこれはdeployサーバとか作ったらわりと普通ですよね?)、deploy時にはそこから一度 .rsync_cache ディレクトリに clone (次回以降はpull)されます。で、デプロイ先には shared ディレクトリに cached-copy というディレクトリができて、local の .rsync_cache から remote の cached-copy に rsync で差分アップロードされます。で、 cached-copy から release_path に日付でディレクトリ cp されて(いや実際はここも rsync です)、最後に symlink の貼替えが行われる、という流れです。

結論

ということで無事に省エネデプロイができるようになりました。

そして最終的には Ruby なので、何したってOKだよね、というところが Ruby 系ツールの良いところなのかどうか、というのは別にして。 *2

*1:Gitとかだと pull とか圧縮してやってるからそこまでコストも高くないのかな?

*2:そしてなんというか、Ruby系ツールはほんとDSLだから、Rubyがわかってればそれが使えるというよりは割とそのツール特有の文法を学ばなきゃいけない所が面倒なところではあるといえばあるのだけど、でもまぁそうはいっても結局最終的にはRubyなのだ