[PHP版] GitレポジトリからWebhookで本番・テストサーバーに自動公開する
Gitレポジトリにpushしたら、対応するドメインにデータを反映させる流れを作りました。Webhook利用して、本番・テストサーバーに自動公開できます。レポジトリサービスはGitlabを使っていますが、他のサービスでも使えるはずです。
公開日:2018年8月24日
全体の流れ
(1) gitレポジトリにpushする (2) pushされたブランチに対応するドメインのサーバーのデータをgit pullで更新する (3) ログを残す
ドメインとブランチの構成
(0) Webhook用ドメイン
URL: hook.example.com サーバー内のパス:/hook.example.com
(1) 本番
ブランチ: master URL: www.example.com サーバー内のパス:/www
(2) 開発
ブランチ: dev URL: dev.example.com サーバー内のパス:/dev.example.com
(3) ステージング
ブランチ: stg URL: stg.example.com サーバー内のパス:/stg.example.com
Gitlabの設定
Webhookというメニューがないためわかりづらいですが、
Settings > Integrations
の画面がWebhookの追加画面です。
ここに、URLとSecret Tokenを入れます。Triggerは、「Push events」のみにチェックを入れます。
本番サーバー側に置くプログラム
(0) まずは設定を書いて置く
// Gitlabの設定
$reposigory_url = "gitlab.com";
$project_name = "Gitlabのプロジェクト名";
$git_user = 'Gitlabのユーザー名';
$git_pass = 'Gitlabのパスワード';
$secret_token = '好きな文字列';
//サーバー側の設定
$git = '/usr/local/bin/git';
$log_file = '.webhook_logs.txt';
$branch_list = [
'master'=>'../www',
'dev'=>'../dev.example.com',
'stg'=>'../stg.example.com',
];
(1) PHPでHTTP Header情報を取得する
自分のGitlabレポジトリからのWebhookなのかを認証するためのTokenを確認します。
Gitlabの設定では、Secret Token」フィールドに予め自分で作成したコードを入れておきます。
$header = getallheaders();
$secret_token = '12345678910';
(2) GitlabからのWebhook以外を拒否する
エラー理由もjson形式で返すようにして、ついでにHTTPレスポンスを401にしておきます
PHPでHTTPレスポンスを返すのは「http_response_code(番号)」でいけます。
PHP: http_response_code - Manual
if(!isset($header['X-Gitlab-Token'])){
http_response_code(401);
echo json_encode(['message'=>'Unauthorized.']);
die;
}
(3) tokenが合わなかったらエラーを返す
// tokenがマッチするか?
if($header['X-Gitlab-Token'] !== $secret_token){
http_response_code(401);
echo json_encode(['message'=>'Token mismatch.']);
die;
}
// 一応Push Hookだけに対応
if($header['X-Gitlab-Event'] !== "Push Hook"){
http_response_code(401);
echo json_encode(['message'=>'Disallowed Event']);
die;
}
(4) Gitlabから送られてくるPOST情報を読み取る
Json形式でPOSTされてくるので、php://inputで情報を読み取ります。
PHPで処理しやすいように,json_decodeで配列に変換します。
$json_string = file_get_contents('php://input');
$json = json_decode($json_string,true);
(5) Push Hookされたブランチ名を取得する
$branch_name = str_replace("refs/heads/", "", $json['ref']);
(6-0) ブランチに対応するディレクトリで、git pullを実行する
if(isset($branch_list[$branch_name])){
$path = $branch_list[$branch_name];
$git_remote = "https://{$git_user}:{$git_pass}@{$reposigory_url}/{$git_user}/{$project_name}.git";
}
(6-1) 初回の場合(対象ディレクトリに.gitディレクトリがない場合)はまずgit clone¥
//初回の場合はまずはクローン
if(!file_exists("{$path}/.git/")){
exec("cd {$path} && ${git} clone {$git_remote} .");
}
(6-2) git pullを実行
// pullする
exec("cd {$path} && ${git} pull {$git_remote} {$branch_name} 2>&1", $output, $exit_status);
(6-3) ログを取る
$date = date("Y-m-d H:i:s");
if ($exit_status > 0) {
$error_msg = "[{$date}] Error: \n";
foreach ($output as $line) {
$error_msg .= " {$line}\n";
}
error_log($error_msg,3,$log_file);
} else {
error_log("[{$date}] Updated successfully\n",3,$log_file);
}
あとはレポジトリにpushするだけ!
masterブランチへpushすれば本番サーバーに、stgブランチにプッシュすれば、stg.example.comにアップデートがされているはずです。
こちらのページを参考にさせていただきました!
GitlabのWebhookを使って簡易デプロイ(Webサーバへ)をしてみた
新着ノート
-
Gitlabの2段階認証下でコンテナレジストリにPushする方法
gitlab
公開日:2020年12月23日
-
HUGO
公開日:2020年4月27日
新着コード
-
cURLでCloudflare APIでキャッシュを削除する
cloudflare
公開日:2020年5月1日
-
iOS Safariでselectを含む要素にoverflow-y:scrollすると横にスクロールする時の対応
iOS
公開日:2020年4月15日