rsyncでアプリケーションを配備

こんにちは、たかはらです。10月になって急に涼しくなってきましたね。私は一年半前からMacのPowerBook G4をつかっています。G4の発熱に加えた今年の夏の暑さは本当に厳しいものがありましたが、最近は涼しくなってずいぶん楽になりました。

私は、ほとんどのソースコードをこのPowerBook G4で書いています。このPowerBook G4からサーバへのアプリケーションの転送(配備:deploy)にはrsyncを利用しています。(少々強引な前フリですが)今日はrsyncをつかったデプロイについてのちょっとした工夫をご紹介します。

rsync-deploy.png

rsyncの基本

rsyncはたくさんのオプションがあり複雑で敬遠されがちですが、基本ファイルコピーをする為のコマンドです。下のようにcpコマンドの様に扱えます。

rsync src.txt dest.txt

以下のようにする事でsshを使ったリモート転送もできます。

rsync -e ssh src.txt takahara@myserver:/path/to/dest.txt

上の例では、myserver(sshのサーバ)にtakaharaでログインしてsrc.txtファイルの転送をします。
ここまではscpでも同じ事ができますね。
下の例はsrcディレクトリの内容をtakahara@myserverdestディレクトリにコピーします。

rsync -e ssh /path/to/src takahara@myserver:/path/to/dest

上の例では、/path/to/dest/srcが作成されます。
下のようにsrcではなくsrc/とすると少し意味が変わり/path/to/destsrcディレクトリは作られませんので注意して下さい。

rsync -e ssh /path/to/src/ takahara@myserver:/path/to/dest

rsyncsrcdestのディレクトリの内容を比較して追加更新の有ったファイルだけアップします。
また、-cオプションを追加する事で、チェックサムにより更新をチェックします。

どのオプションを利用するか

私が、アプリケーションのデプロイに使うrsyncの基本形は下の通りです。

rsync -azc --delete --force -e ssh\
    /path/to/src/ takahara@myserver:/path/to/dest

このオプションを毎度入力するのが面倒なので、rsyncaというシェルスクリプトを作成しています。

#!/bin/sh
rsync -azc --delete --force -e ssh $*

パスの通った場所に置いておくと便利です。

rsync-deploy

さて、ここからが本題です。プロジェクトのデプロイにはrsyncでディレクトリを同期すれば良い訳ですが、意図しないファイルがサーバへデプロイされる事を防ぐ為に確認できるようなスクリプトを作っています。

#!/bin/sh
# server=user@server dir=/path/to/dir rync-deploy
dest=${server}:${dir}
 
rsync_options="-azvC -c --force --delete -e ssh"
 
if [ -f rsync_exclude.txt ]; then
    rsync_options="--exclude-from=rsync_exclude.txt ${rsync_options}"
fi
 
command=$1
 
case $command in
    go)
    rsync --progress $rsync_options ./  $dest
    ;;
    diff)
    files=`rsync $rsync_options --dry-run ./ $dest |grep -v ".*/$"`
    for file in $files;
    do
        if [ -f $file ]; then
        tempfile=`tempfile`
        touch ${tempfile}
        scp ${dest}/${file} ${tempfile} 2>/dev/null
        diff -uN ${tempfile} ${file}
        rm ${tempfile}
        fi
    done
    ;;
    *)
    rsync $rsync_options --dry-run ./ $dest |grep -v ".*/$"
    ;;
esac

これもパスの通った場所に置いておくと便利です。

こんな感じで利用します。

server=user@server dir=/path/to/dir rsync-deploy

プロジェクト毎に./deployというファイルを作って上の内容を書いておく事で単に./deployとして実行できます。

利用方法

このスクリプトでは下の様に実行しただけでは実際に転送は行われず転送予定のファイル一覧が表示されます。

./deploy

所謂、dry-runするわけです。このファイルのリストを見て転送されるファイルが正しければ、下のようにgoをつけて実行します。

./deploy go

./deployと実行した時に表示される転送予定ファイルリストとリモートサーバとの差分を見るには以下のようにします。

./deploy diff

これで修正内容を確認して、改めて./deploy goとすれば安心です。

同期しないファイルの設定

もし、予め転送対象から除きたい場合には、deployスクリプトと同じディレクトリにrsync_exclude.txtを作成して以下のように書いておきます。

deploy
*~
.svn/
CVS/

このようにする事で、転送対象から外す事ができます。


ディノでは開発手法なるべく標準化して会社で統一するようにしているのですが、
開発環境はあえて統一していません。

そのため、アプリケーションのデプロイ方法は人によってまちまちなのです。もしこれをご覧になった方で俺はこうやっているよ〜という方がいらっしゃったら是非教えて下さい。


  • 2007-10-3 追記: rsync オプションに -v を追加しました。

コメント / トラックバック 2 件

#1 ryer 2007/10/09 13:40

ウェブのGUIから上記のようなことをやるようにしていました。
その場合には、上でいうdeployファイルはhttpdからアプリケーションの設置ユーザでsudoできるようにしておくとよいです。
本番サーバが複数あるときは並列同期すると2~3割くらい早くなります。

#2 sasimi 2007/10/23 19:05

deployなので影響する場合は少ないとおもいますがzオプション( –compress)はあまり好きではありません。
経験上100MBオーダーのファイルがある場合に転送時にほぼ間違いなくコケます。
dailyのバッチをまわしていていつのまにかrsyncがこけるようになったという場合は、
ひそかに配布元に100MB程度のアーカイブが作成されていたということが多いです。

コメントする