50
55

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Gitプッシュでブランチごとにステージング環境生成or本番反映させる

Last updated at Posted at 2016-11-29

#概要

「masterをプッシュで本番反映」をやっている記事はいくつかあったものの、ブランチごとに自動でステージング(テスト環境)が作られるような仕組みは見当たらなかったので書いてみる。

マージ未定の実験的なブランチをWeb上で確認したり、ローカル環境のないディレクターやデザイナーに作業ブランチの内容を確認してもらう際に役に立つはず。

Gitフック経由のサイト更新はFTPもサーバーへのログインも必要なく、ただpushするだけなので非常に便利だと思う。

※以下、ある程度のサーバーサイドの知識を要する説明になっているので注意

##最終的に実装する機能

  • masterをリモートリポジトリにpushすると、masterの内容が本番サイトであるhttp://プロジェクト名.com/に取り込まれる。

  • hogeというブランチを切ってプッシュすると、http://hoge.プロジェクト名.com/というhogeブランチの内容が反映されたステージングができあがる。

  • hogeブランチを削除するとステージングも消える。

これらを、gitのサーバーサイドフック(シェルスクリプト)+Apacheの設定で実装する。
他に何かのサービスを利用したりインストールしたりは特にない。

##前提条件

  • 対象サーバーにgitリポジトリと本番環境・ステージングが同居している ※1
  • 「*.プロジェクト名.com」のDNSレコードが対象サーバーに向いている

※1 git hubなど外部のリポジトリを利用している場合、各サービスのwebフックなどを利用し、本稿で作るgitフックをHTTP経由で発火させる必要がある。

##完成後のディレクトリ構成

var
 └www
   ├git
   │ ├プロジェクトA.git ←リモートリポジトリたち
   │ └プロジェクトB.git
   │
   └html
     ├プロジェクトA
     │ ├master ←プロジェクトA.gitのmasterブランチをクローンしたもの
     │ └develop ←プロジェクトA.gitのdevelopブランチをクローンしたもの
     │
     └プロジェクトB
       ├master
       ├develop
       └etc...

masterやdevelopに各ブランチのソースが入りweb公開される。

#実装

##下準備

以下についての手順は省略する。

  • サーバーにApacheとgitをインストールする。
  • サーバーにgitリポジトリを作成し、ローカルから利用できるようにする。
  • /var/www/htmlにプロジェクトディレクトリを作成する。※2
  • プロジェクト名.com*.プロジェクト名.comのDNSレコードをサーバーに向ける。

※2 この配下のmasterやdevelopといったディレクトリは勝手に生成されるので作成不要

##手順1:Apacheを設定
「ブランチ名.プロジェクト名.com」でアクセスされた際に「/var/www/html/プロジェクト名/ブランチ名」を参照するように設定する。
また、ブランチ名を省略して、「プロジェクト名.com」でアクセスされた場合はmasterをみるようにする。

VirtualDocumentRootを使うので、mod_vhost_aliasが無効になっている場合有効にしておく。

/etc/httpd/conf/httpd.conf
LoadModule vhost_alias_module modules/mod_vhost_alias.so
# 場所は環境によって異なる

バーチャルホストの設定ファイルを開き、以下の設定を追加する。

http://ブランチ名.プロジェクト名.comのようにプロジェクト専用のドメインを取得している場合、

/etc/httpd/conf.d/vhosts.conf
<VirtualHost *:80>
    ServerName プロジェクト名.com
    ServerAlias *.プロジェクト名.com
    VirtualDocumentRoot "/var/www/html/プロジェクト名/%1"
</VirtualHost>
<VirtualHost *:80>
    ServerName プロジェクト名.com
    ServerAlias プロジェクト名.com
    DocumentRoot "/var/www/html/プロジェクト名/master"
</VirtualHost>

http://ブランチ名.プロジェクト名.ドメイン名.comのように、サブドメインへ複数のプロジェクト名を動的に設定したい場合、

/etc/httpd/conf.d/vhosts.conf
<VirtualHost *:80>
    ServerName ドメイン名.com
    ServerAlias *.*.ドメイン.com
    VirtualDocumentRoot "/var/www/html/%2/%1"
</VirtualHost>
<VirtualHost *:80>
    ServerName ドメイン名.com
    ServerAlias *.ドメイン.com
    VirtualDocumentRoot "/var/www/html/%2/master"
</VirtualHost>

記述後、apacheを再起動する。

##手順2:gitのサーバーサイドフックを記述
サーバーサイドフックは、リモートリポジトリへのプッシュをトリガーに発火する処理。
今回は、/var/www/git/プロジェクト名.git/hooks/内にpost-updateというファイルを作成する。

post-updateはプッシュされた際にブランチごとに発火する。その際「refs/heads/master」のような引数が設定される。

今回シェルスクリプトでやること、

  1. 引数を元に、git rev-parseでプッシュされたブランチ名を取得する
  2. git rev-parseに失敗(結果と引数がイコール)した場合ブランチ削除とみなす
    3-A. ブランチ削除の場合、対応するステージングを削除
    3-B. ブランチに対するステージングが存在しないならクローンして作成
    3-C. 既に存在する場合はクローン済みのステージングをプル
/var/www/git/プロジェクトA.git/hooks/post-update
#!/bin/bash

repo=/var/www/git/プロジェクト名.git
dir=/var/www/html/プロジェクト名/
name=$(git rev-parse --symbolic --abbrev-ref $1)

# delete chk
delete=0
if [ $name = $1 ]; then
  name=${name#refs/heads/}
  delete=1;
fi

# pull or clone or delete
if [[ $name =~ ^[a-z0-9-]+$ ]]; then
  if [ $delete = 1 ] && [ $name != master ]; then
    echo $dir$nameを削除
    rm -rf $dir$name
  elif [ -e $dir$name ]; then
    echo $dir$nameをプル
    cd $dir$name
    git --git-dir=.git pull
  else
    echo $dir$nameをクローン
    cd $dir
    git clone -b $name $repo $name
  fi
fi

※ハイフン以外の記号や大文字が含まれるブランチは無視する
 (つまりステージング不要なブランチは「feature/hoge」のような名前にすればよい)
rm -rfしている箇所もあるので実装は慎重かつ自己責任で。

フックには実行権限を付与する。

$ sudo chmod +x /var/www/git/プロジェクトA.git/hooks/post-update

##手順3:パーミッションの設定

プッシュするユーザーが「git配下の書き込み権限」と「html配下の書き込み権限」を持っている必要がある。

###gitリモートリポジトリをhttps経由で利用する場合:
プッシュもフックの実行もapacheが行うことになるので、各ディレクトリの所有者をapacheにしておけばよい。

$ sudo chown apache:apache -R /var/www/git
$ sudo chown apache:apache -R /var/www/html

###gitリモートリポジトリをSSH経由で利用する場合:

ログインユーザーがプッシュやフックを実行することになる。
好みにもよるが、例えば各ディレクトリの所有ユーザーとグループをapacheに設定しておいて、プッシュするユーザーをapacheグループに追加するなど。

$ sudo chown apache:apache -R /var/www/git
$ sudo chown apache:apache -R /var/www/html
$ sudo chmod g+w -R /var/www/git
$ sudo chmod g+w -R /var/www/html
$ sudo usermod -aG apache ユーザー名

##確認
プッシュ後、設定したURLでそのブランチの内容が閲覧できることを確認する。

ステージング削除の際は下記コマンドでリモートブランチを削除する必要がある。

$ git push origin :ブランチ名
# ブランチ名の前のコロンを忘れずに

恐らく、SourceTreeなどのgitクライアント経由でリモートブランチを削除しても、ステージングは削除されないので注意。

50
55
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
50
55

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?