- Gitにpushしたら自動でサーバーに同期したい
- ブランチごとに確認できる環境を自動でwebに用意したい
パターンA:サブドメインでブランチを分ける
やりたいこと
こんな感じでそれぞれのブランチにアクセスできる環境を自動化したい。
http://ブランチ.プロジェクト.ドメイン
http://project.domain.com - masterブランチ
http://develop.project.domain.com - developブランチ
http://feature-1.project.domain.com - feature/1ブランチ
必要なもの
- DNS設定 - *.domain.comみたいなワイルドカード指定の必要がある
- Apache - じゃなくてもいいのかもだけど、今回、調べたのがApacheなので
- GithubやBacklogなどの設定 - リポジトリと、認証鍵の設定とか
- cloneとかpullするスクリプト - 今回はPHPからのシェルコマンドでやりました
方法
1. DNS設定
必要なものに書いたけど、とりあえずDNSで*.domain.comにアクセスできるようにする。
できない場合(権力とか武力とかが足りない場合)はパターンBの方を検討してください。
DNSの設定が活きるまでにしばらく時間がかかると思うので、先にやっておいた方が良さそう。
AレコードでサーバーのIPアドレスと「*.domain.com」を紐づける
2. サーバーの準備
以下の記事を参考にしました。
Gitプッシュでブランチごとにステージング環境生成or本番反映させる
こんな感じのディレクトリが最後に完成します。
キモは、master/html、develop/htmlなどを、各プロジェクトで揃えておくこと。
ここが揃ってないとApacheのconfを毎回書くのでイマイチです。
最初は手動でディレクトリを作っておいてテストしたほうが楽かもしれません。
GithubやBacklog
├プロジェクトA.git
└プロジェクトB.git
自サーバー内
└var
└www
└html
├sync-git ←同期用のPHPを置くところ
│ └master ←一応、他と同じに合わせておく
│ └html
│ ├git-ssh.sh ←鍵指定をするところ
│ ├sync_github.php ←Githubからの受け付け用
│ └sync_backlog.php ←Backlogからの受け付け用
│
├project-a
│ ├master ←プロジェクトAのmaster
│ │ ├html ←ここがmasterの公開ディレクトリ
│ │ └cgi-bin ←お好みでcgi-binもここ
│ │
│ └develop ←プロジェクトAのdevelop
│ ├html ←ここがdevelopの公開ディレクトリ
│ └cgi-bin
│
├project-b
│ └...
│
├...
あと、/var/www/htmlのユーザーをapache:apacheにして書き込みできるようにしておいてください。
apacheさんじゃない場合は以下のPHPとかで確認できると思います。
<?php echo exec('whoami'); ?>
Apacheの設定
/etc/httpd/conf.d/vhost.confあたりにVirtualHostを書きます。
既存の設定が違うところにあるかもなので、無かったら/etc/httpd/conf/httpd.confなども見てあげてください。
ちなみにcgi-binの指定がうまくいかない場合、/etc/httpd/conf/httpd.confなどに全共通のScriptAliasが書いてあるとダメみたいなのでコメントアウトすると良いです。
以下のようなVirtualHostとDirectoryを書きます。
これが共通設定みたいな感じです。
## Project Alias
# branch
<VirtualHost *:80>
ServerName domain.com
ServerAlias *.*.domain.com
VirtualDocumentRoot "/var/www/html/%2/%1/html"
VirtualScriptAlias "/var/www/html/%2/%1/cgi-bin/"
</VirtualHost>
# master
<VirtualHost *:80>
ServerName domain.com
ServerAlias *.domain.com
VirtualDocumentRoot "/var/www/html/%1/master/html"
VirtualScriptAlias "/var/www/html/%1/master/cgi-bin/"
</VirtualHost>
# DocumentRoot
<Directory "/var/www/html/*/*/html/">
Options +Indexes +Includes +MultiViews +FollowSymlinks
AddOutputFilter Includes;Deflate html
DirectoryIndex index.php index.html
AllowOverride All
Satisfy Any
Allow from all
</Directory>
# Script
<Directory "/var/www/html/*/*/cgi-bin/">
Options +Indexes +Includes +MultiViews +FollowSymlinks +ExecCGI
AddHandler cgi-script .cgi
AddHandler cgi-script .pl
AddOutputFilter Includes html
AllowOverride All
Satisfy Any
Allow from all
</Directory>
個別のプロジェクト設定は、VirtualHostだと共通設定の前、Directoryなら共通設定の後の方が良いみたい。
この辺は理解が足りなくて試行錯誤の結果なので、分かる人はいい感じにしてください。
以下はプロジェクトAにBasic認証をかける場合。
## プロジェクトA
# master
<VirtualHost *:80>
ServerName project-a.domain.com
ServerAlias project-a.domain.com
DocumentRoot "/var/www/html/project-a/master/html"
ScriptAlias /cgi-bin/ "/var/www/html/project-a/master/cgi-bin/"
</VirtualHost>
# branch
<VirtualHost *:80>
ServerName project-a.domain.com
ServerAlias *.project-a.domain.com
VirtualDocumentRoot "/var/www/html/project-a/%1/html"
VirtualScriptAlias "/var/www/html/project-a/%1/cgi-bin/"
</VirtualHost>
## Project Alias
...
## プロジェクトA
# DocumentRoot
<Directory "/var/www/html/project-a/*/html/">
...
AuthType Basic
AuthName "Development"
AuthUserFile /var/www/password/project-a/.htpasswd
Require valid-user
Satisfy Any
Order allow,deny
</Directory>
# Script
<Directory "/var/www/html/project-a/*/cgi-bin/">
...
AuthType Basic
AuthName "Development"
AuthUserFile /var/www/password/project-a/.htpasswd
Require valid-user
Satisfy Any
Order allow,deny
</Directory>
設定できたらconfigtestして、Apacheを再起動。
3. 同期用PHPの設置
とりあえず、今回使ったPHPは以下に置いておきました。
GithubとBacklogで、使うPHPが違います。
https://github.com/yukihirog/server-sync-git
これらを、
/var/www/html/sync-git/master/html
の中に置いてみます。
設定がうまくできていれば以下のようなURLでアクセスできるはず。
http://sync-git.ドメイン/sync_github.php
http://sync-git.ドメイン/sync_backlog.php
http://master.sync-git.ドメイン/sync_github.php
http://master.sync-git.ドメイン/sync_backlog.php
4. Webhookの設定
鍵の準備
以下を参考にしました。
apache のデフォルト実行ユーザ www-data で github や bitbucket にSSH 接続する
GithubもBacklogも鍵を使ってアクセスします。
なので、サーバーで鍵を作って、それぞれのユーザーに設定しておくと便利です。
$ cd /var/www/.ssh
$ sudo ssh-keygen -t rsa
$ cat id_rsa.pub
$ sudo vi config
Host github.com
Hostname github.com
IdentityFile /var/www/.ssh/id_rsa
User git
Port 22
$ sudo -u apache ssh -vT github.com
$ sudo -u apache ssh -vT スペース名@スペース名.git.backlog.com
/var/www/.sshディレクトリがない場合は作ってください。
ssh-keygenの設定はエンターエンターツターンツターンでいいはず。
最後のcatした後に公開鍵の文字列が出てくるのでコピーして登録します。
(プロジェクトごとのDeploy keyの扱いが大変なのでユーザーに設定してます。)
Githubだとログインして以下。
https://github.com/settings/keys
Backlogはスペースごとに、ログインして以下。
https://***.backlog.com/EditUserSshKey.action
Webhookの追加
GithubのリポジトリやBacklogのプロジェクトごとに以下の設定でWebhookを追加します。
「リポジトリ > Settings > Webhooks」で以下の設定
Payload URL: http://sync-git.ドメイン/sync_github.php
Content type: application/x-www-form-urlencoded
Secret: sync_github.phpの「$SECRET_KEY = 'SECRET_KEY';」の中身
Just the push event.
Active
「プロジェクト > プロジェクト設定 > Webhook」で以下の設定
WebHook URL: http://sync-git.ドメイン/sync_backlog.php?space=スペース名
(スペース名は***.backlog.comの***の部分)
通知するイベント: Gitプッシュ
うまくいっていると、これで次のpushから動きます。
以降はプロジェクト作ったらWebhooksの設定をすればOKです。
うまくいかない場合
- Githubの場合は上記設定のページにあるRecent DeliveriesでResponseを見ることができます。
- PulledとかCloneとか言う割に、肝心のそこだけエラーチェックとメッセージが出ません。
- cloneされるはずなのにmasterとかのディレクトリができていない場合、だいたい鍵の指定ができてなくてcloneできてません。すみませんがその辺は弱いので「Github deploy key サーバー同期」などで検索してみてください。
- もしくはディレクトリの書き込み権限です。
パターンB:CookieとRewriteRuleでブランチを分ける
やりたいこと
/branch.phpとかにアクセスして、プルダウンでブランチ選択したら全体がそのブランチになるようにしたい。
ただし、プロジェクト選択とかcgiはうまくないかも。
必要なもの
- Apache - じゃなくてもいいのかもだけど、今回、調べたのがApacheなので
- GithubやBacklogなどの設定 - リポジトリと、認証鍵の設定とか
- cloneとかpullするスクリプト - 今回はPHPからのシェルコマンドでやりました
方法
1. サーバーの準備
パターンBでもパターンAとほぼ同じです。
GithubやBacklog
├プロジェクトA.git
└プロジェクトB.git
自サーバー内
└var
└www
└html
└project-a
├git-ssh.sh ←鍵指定をするところ
├sync_github.php ←Githubからの受け付け用
├sync_backlog.php ←Backlogからの受け付け用
├branch.php ←ブランチを選択するためのページ
├master ←プロジェクトAのmaster
│ ├html ←ここがmasterの公開ディレクトリ
│ └cgi-bin
│
└develop ←プロジェクトAのdevelop
├html ←ここがdevelopの公開ディレクトリ
└cgi-bin
Apacheの設定
/etc/httpd/conf.d/vhost.confあたりにVirtualHostを書きます。
以下のようなVirtualHostを書きます。
<VirtualHost *:80>
ServerName domain.com
ServerAlias domain.com
DocumentRoot "/var/www/html/project-a/"
<IfModule mod_rewrite.c>
RewriteEngine On
# Cookieありの時のCGI
RewriteCond %{REQUEST_FILENAME} !branch.php
RewriteCond %{REQUEST_URI} ^/cgi\-bin/.*
RewriteCond %{HTTP_COOKIE} (.*)BRANCH=([^;]+)(.*)
RewriteRule ^(.*)$ /%2$1 [L]
# Cookieありの時のCGI以外
RewriteCond %{REQUEST_FILENAME} !branch.php
RewriteCond %{HTTP_COOKIE} (.*)BRANCH=([^;]+)(.*)
RewriteRule ^(.*)$ /%2/html$1 [L]
# Cookie無しの時のCGI
RewriteCond %{REQUEST_FILENAME} !branch.php
RewriteCond %{REQUEST_URI} ^/cgi\-bin/.*
RewriteRule ^(.*)$ /master$1 [L]
# Cookie無しの時のCGI以外
RewriteCond %{REQUEST_FILENAME} !branch.php
RewriteRule ^(.*)$ /master/html$1 [L]
</IfModule>
</VirtualHost>
mod_rewriteを使って、Cookieに「BRANCH=develop」とか書かれていたら「/index.html」を「/develop/html/index.html」とかに読み変える設定をしています。
2. ブランチ選択用のPHPの設置
こんな感じのPHPを、プロジェクト/html/branch.phpとして設置します。
<?php
$current = '';
if (isset($_GET['BRANCH'])) {
setcookie('BRANCH', $_GET['BRANCH'], time()+60*60*24*30*12, '/');
$current = $_GET['BRANCH'];
} else if ($_COOKIE['BRANCH']) {
$current = $_COOKIE['BRANCH'];
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Branch Selector</title>
</head>
<body>
<p>現在のブランチ:<?php echo $current; ?></p>
<form>
<p>
<label>
ブランチ:
<select name="BRANCH">
<?php
$files = scandir('.');
foreach ($files as $index => $file) {
if (is_dir($file) && $file != '.' && $file != '..') {
if ($current === $file) {
echo "<option selected>$file</option>";
} else {
echo "<option>$file</option>";
}
}
}
?>
</select>
</label>
<input type="submit" value="決定">
</p>
</form>
</body>
</html>
3. 同期用PHPの設置
あとはパターンAと同じです。
4. Webhookの設定
あとはパターンAと同じです。