背景
静的サイトのソースをGithubで管理し、pushされた時にwebhookを動かし、外部サーバでgit pullすることで自動デプロイする。
よくやることだが、意外とapache前提の情報が多く、nginxに初めて触る&PHP普段書いてないため若干ハマった。
個人用に注意点をまとめておく。
構成
ソース管理:Github
外部サーバ環境:さくらのVPS, CentOS7, nginx, webhook用のスクリプトはPHPで作成
SSH認証の準備
以下の記事を参考にSSH鍵を設定し、接続のテストを行う。
http://qiita.com/shizuma/items/2b2f873a0034839e47ce
ただし、気をつけないといけないのは今回はnginx上で行うということ。
webhook用スクリプトの実行ユーザがnginxとなるので、nginxユーザでGithubにssh接続し、git pullしてこれないといけない。
nginxのデフォルトのSSH鍵の置き場は以下のため、ここにSSH鍵を配置。
/var/cache/nginx/.ssh
接続をテストするときも、nginxユーザでテストする。
sudo -u nginx ssh -T git@gitlab.com
webhook用のスクリプトを準備
git pullしてくるスクリプトは以下を参考にさせていただき準備した。
http://qiita.com/oyas/items/1cbdc3e0ac35d4316885
ただし、このPHPのスクリプトもapache前提となっていてnginx上では動かないので修正。
具体的には、getallheadersv()はapacheに依存しているため動かない。getallheaders()を使わずにリクエストヘッダーの値を取得する。
修正したものが以下のソース
<?php
// 設定
$LOG_FILE = dirname(__FILE__).'/hook.log';
$SECRET_KEY = 'your key';
$postdata = file_get_contents("php://input");
$hmac = hash_hmac('sha1', $postdata, $SECRET_KEY);
if ( isset($_SERVER['HTTP_X_HUB_SIGNATURE']) && $_SERVER['HTTP_X_HUB_SIGNATURE'] === 'sha1='.$hmac ) {
$payload = json_decode($postdata, true); // 受け取ったJSONデータ
// ここに実行したいコードを書く
exec('git pull 2>&1');
file_put_contents($LOG_FILE, date("[Y-m-d H:i:s]")." ".$_SERVER['REMOTE_ADDR']." git pulled: ".$payload['after']." ".$payload['commits'][0]['message']."\n", FILE_APPEND|LOCK_EX);
} else {
// 認証失敗
file_put_contents($LOG_FILE, date("[Y-m-d H:i:s]")." invalid access: ".$_SERVER['REMOTE_ADDR']."\n", FILE_APPEND|LOCK_EX);
}
Githubにwebhookを登録
上記で作成したスクリプトをGithubの対象プロジェクトのwebhookに登録。
以上。