デプロイ時の負荷対策の一解決策になる、、、かも。
JGitのインストール
- http://eclipse.org/jgit/
- 『org.eclipse.jgit.pgm-1.3.0.201202151440-r.sh』はus-east-1しか操作できないバグあり
- jgitに名前を変えて、ローカルマシンとデプロイ対象のサーバで実行できるようにしておく
ローカルマシンとデプロイ対象のホームディレクトリに『~/.jgit_s3』を作成。
accesskey: hoge secretkey: fuga acl: private
リポジトリの作成
参考: http://d.hatena.ne.jp/winebarrel/20110206/p1
ローカルマシンで適当なリポジトリを作成して、S3にpushしておく。
s3cmd mb s3://my.git.repos mkdir myapp cd myapp/ git init touch hello.c git add hello.c git commit -m 'first commit' git remote add origin amazon-s3://.jgit_s3@my.git.repos/myapp.git/ git config branch.master.remote origin git config branch.master.merge refs/heads/master jgit push
Capistranoプロジェクトの作成
Rubyのライブラリ探索パスに『capistrano/recipes/deploy/scm/jgit.rb』を置く。
(プロジェクトの直下にディレクトリを作成する、、、とか)
require 'capistrano/recipes/deploy/scm/git' module Capistrano module Deploy module SCM class Jgit < Git default_command "jgit" def checkout(revision, destination) jgit = command execute = [] execute << "#{jgit} clone #{variable(:repository)} #{destination} 2> /dev/null" execute << "cd #{destination} && #{jgit} checkout #{revision}" execute.compact.join(" && ").gsub(/\s+/, ' ') end # of checkout # リモートでのリビジョン取得にちょっと難あり、、、 # デプロイ対象が複数の場合、リビジョンを統一するようにしないと # ローカルで実行するようにすれば大丈夫かな? def query_revision(revision) jgit = command result = nil tmp_dir = "/tmp/#{variable(:application)}.#{Time.now.to_i}" configuration.run(<<-EOS) {|conn, out, res| result = res} #{jgit} clone #{variable(:repository)} #{tmp_dir}; cd #{tmp_dir}; git log -1 | awk '/^commit /{print $2}'; cd ..; rm -rf "#{tmp_dir}"; EOS result end # of query_revision end # of class Jgit end end end
Capfileはこんな感じ。
load 'deploy' # おまじない set :application, 'myapp' set :scm, :jgit set :user, 'ec2-user' set :repository, 'amazon-s3://.jgit_s3@my.git.repos/myapp.git/' set :deploy_to, '/home/ec2-user/myapp' role :app, 'ec2-XXX-XXX-XXX-XXX.ap-northeast-1.compute.amazonaws.com' # Railsプロジェクトではない場合は、以下を無効化 namespace :deploy do task(:restart) {} task(:finalize_update) {} end
実行結果
~/work/cap-proj-jgit$ cap deploy
* executing `deploy'
* executing `deploy:update'
** transaction: start
* executing `deploy:update_code'
* executing "jgit clone amazon-s3://.jgit_s3@my.git.repos/myapp.git/ /tmp/myapp.1335282762;\\\n cd /tmp/myapp.1335282762;\\\n git log -1 | awk '/^commit /{print $2}';\\\n cd ..;\\\n rm -rf \"/tmp/myapp.1335282762\";"
servers: ["ec2-XXX-XXX-XXX-XXX.ap-northeast-1.compute.amazonaws.com"]
[ec2-XXX-XXX-XXX-XXX.ap-northeast-1.compute.amazonaws.com] executing command
command finished in 5702ms
* executing "jgit clone amazon-s3://.jgit_s3@my.git.repos/myapp.git/ /home/ec2-user/myapp/releases/20120424155249 2> /dev/null && cd /home/ec2-user/myapp/releases/20120424155249 && jgit checkout 93dac3617fd6fddd578306c81a96b3569c520ad8 && (echo 93dac3617fd6fddd578306c81a96b3569c520ad8 > /home/ec2-user/myapp/releases/20120424155249/REVISION)"
servers: ["ec2-XXX-XXX-XXX-XXX.ap-northeast-1.compute.amazonaws.com"]
[ec2-XXX-XXX-XXX-XXX.ap-northeast-1.compute.amazonaws.com] executing command
** [ec2-XXX-XXX-XXX-XXX.ap-northeast-1.compute.amazonaws.com :: out] Initialized empty Git repository in /home/ec2-user/myapp/releases/20120424155249/.git
** [ec2-XXX-XXX-XXX-XXX.ap-northeast-1.compute.amazonaws.com :: out] From amazon-s3://.jgit_s3@my.git.repos/myapp.git/
** * [new branch] master -> origin/master
command finished in 5931ms
* executing `deploy:finalize_update'
* executing `deploy:create_symlink'
* executing "rm -f /home/ec2-user/myapp/current && ln -s /home/ec2-user/myapp/releases/20120424155249 /home/ec2-user/myapp/current"
servers: ["ec2-XXX-XXX-XXX-XXX.ap-northeast-1.compute.amazonaws.com"]
[ec2-XXX-XXX-XXX-XXX.ap-northeast-1.compute.amazonaws.com] executing command
command finished in 94ms
** transaction: commit
* executing `deploy:restart'
[ec2-user@ip-XX-XX-XX-XX ~]$ ls -R myapp/
myapp/:
current releasesmyapp/releases:
20120424155249myapp/releases/20120424155249:
hello.c REVISION