2012-02 << 2012-03 >> 2012-04

2012-03-18 (日)

*Github に push したら自動的にデプロイする

特定のリポジトリに push したら hooks/post-receiveでサービスをデプロイという設定をしたのですが,githubにもpost-receiveがあるっぽいです.せっかくなので使いたい.

http://help.github.com/post-receive-hooks/

HTTPで通知が飛んでくるので適当なcgiを叩かせれば簡単にできそうです.

httpdを起動している apache ユーザにファイルの配置をやらせたくないので,デプロイ用のユーザで処理させたい.あと,将来的に複数サーバへのデプロイもまとめてやる可能性も考慮してssh経由でやることに.

あとはこの辺を参考に→ http://d.hatena.ne.jp/viver/20110402/p1

  • httpdのユーザー : apache
  • デプロイ処理をするアカウント : svn

gitなのにsvnさんがデプロイするのは気にしない.

apache

まず,ssh-keygenでデプロイ用キーを作ります.パスフレーズ無しで.ちょっと怖いですが,秘密鍵をapacheユーザで読めるところに配置してください.どうせデプロイコマンド以外は叩けないので,そんなにリスクは高くないはず.

次にデプロイ時にアクセスするCGIを設置.とても適当なのであとでちゃんと書く.

deploy.cgi :

#!/usr/bin/ruby -Ku
require 'cgi'

cgi = CGI.new

project = cgi.params['project'].join
unless project =~ /\A[\w-]+\z/m
  puts cgi.header({'type'=>'text/html', 'charset'=>'UTF-8'})
  puts "INVALID_PROJECT"
  exit
end

$stderr = $stdout

puts cgi.header({'type'=>'text/html', 'charset'=>'UTF-8'})
puts `ssh -i /var/www/svn_id_rsa svn@localhost deploy #{project}`
puts "OK"

/var/www/svn_id_rsa は実際の場所にしてください.

svn

まず,デプロイ用スクリプトを適当に書きます.

~/deploy/update.rb:

#!/usr/bin/ruby -Ku

project = ARGV[1]
unless project =~ /\A[\w-]+\z/m
  puts "INVALID_PROJECT"
  exit
end

unless File.exists?(File.dirname(__FILE__)+"/"+project)
  puts "NOT_FOUND"
  exit
end

puts "deploy:#{project}"

system("cd #{File.dirname(__FILE__)+"/"+project}; git pull")
system("cd #{File.dirname(__FILE__)}; sh #{project}-update.sh")

とてもいい加減ですが,gitからpullしてきた後,[プロジェクト名]-update.shを実行しています.ファイルの配置とか色々はそっちのシェルスクリプトでやる感じで.

次に,apacheユーザで作った公開鍵を.ssh/authorized_keysに追加.

このとき,

command="./deploy/update.rb $SSH_ORIGINAL_COMMAND",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa ~~~

みたいな感じに書いて,変なコマンドは実行できないようにしておく.

ここで,./deploy/hoge にプロジェクトhogeをcloneしておきます.必要なら,hoge-update.shも作っておく.

あと,事前にknown_hostsに登録しないとだめなので,最初に一度だけapacheユーザでログインしておく.

sudo -u apache ssh -i /var/www/svn_id_rsa svn@localhost deploy hoge

ここで,.ssh/known_hostsが作れないとか,秘密鍵のパーミッションがおかしいとか言われたら,良い感じに直してください.

おわり

あとは,deploy.cgi?project=hogeをブラウザから叩いて,正常に処理が走ることを確認したら,githubのpost-receiveに登録して終わり.

githubから来るpayloadまったく見ていないとか,気にしない.

2012-02 << 2012-03 >> 2012-04