初心者がGitHubからヘテムルに自動デプロイする環境を構築するまでのお話

# キッカケ

もともとロリポップライトユーザーだったわたくし。
ライトプランだとDBが1つしか使えません。
プランアップするか、ヘテムルやさくらなど別のレンタルサーバーにするか悩んでいました。

調べてみたら、ちょうどヘテムルが初期費用(3900円)が無料キャンペーン中！
無料期間中に支払いをしなければ契約にならないらしいので、お試し利用することにしました。
サクサクとフォーム入力していったら、いつのまにか3ヶ月分の料金支払いが済んでました／(^o^)＼ﾅﾝﾃｺｯﾀｲ

会社で先輩が設定してくれた自動デプロイ環境が便利だったので、自分でも構築してみたいと思います。





# 自動デプロイとは


> デプロイとは、主にネットワークを通じて提供されるWebアプリケーションなどのシステム開発工程において、システムを利用可能な状態にすることである。
> 
> デプロイ（deploy）という言葉は元々、配置する、展開するといった意味の英語である。デプロイはソフトウェアのリリースやインストールも含んだ意味の広い言葉であり、開発環境からステージング環境へシステムを反映させることも、ステージング環境から本番環境へ反映させることも、「デプロイする」と表現できる。
> 
> :point_right_tone2: [IT用語辞典 Weblio辞書 > デプロイとは](http://www.weblio.jp/content/デプロイ)

ひらたく言うと、**GitHubで管理してるソースをFTP使わないで自動反映させる仕組み**と理解しています。





# 目指すゴール

1. **futureブランチ**で開発（ローカル）
1. **developブランチ**にpushすると、自動でリモート開発環境にも反映（例 http://develop.xxxxx.xx/ ）
1. **masterブランチ**にpushすると、自動でリモート本番環境にも反映（例 http://xxxxx.xx/ ）

↑でも2と3は技術的に同じことしてるので、この記事では3だけ書きます。

※ブランチモデルについての考え方は下記が参考になりました。
:point_right_tone2: [Qiita > Gitのブランチモデルについて](http://qiita.com/okuderap/items/0b57830d2f56d1d51692)
:point_right_tone2: [サルでも分かるGit入門 > トピックブランチと統合ブランチでの運用例](http://www.backlog.jp/git-guide/stepup/stepup1_5.html)

作りたいディレクトリ構造はこんな感じ↓

```:ローカル
web/                    # ヘテムルとディレクトリ名を揃えたけど何でもどこでもOK
 ├ _hook.php            # webhookが叩くプログラム
 │
 └ xxxxx.xx/            # ドメインをそのままディレクトリ名にする
    ├ .git/             # Gitが自動生成するファイル
    ├ public/           # プログラムソース置き場
    └ private/          # 仕様書やpsdなど、プログラムとは関係ないけどGitで管理したい資料置き場
```

```:リモート(ヘテムル)
web/
 ├ _hook.php            # webhookが叩くプログラム
 │
 └ xxxxx.xx/            # ドメインをそのままディレクトリ名にする
    ├ develop/          # developブランチがMergeされると自動でpull
    │  ├ .git/          # 非公開
    │  └ public/        # 制限付き公開(IP制限かけて自分だけサブドメインdevelop.xxxxx.xxで動作確認できるようにする)
    │                   # privateディレクトリはpullされないようにする(今回未実装)
    │
    └ master/           # masterブランチがMergeされると自動でpull
       ├ .git/          # 非公開
       └ public/        # 一般公開
                        # privateディレクトリはpullされないようにする(今回未実装)
```





# 私の環境

| | 環境 |
|:---|:---|
| ローカルPC | MacBookAir OSX |
| レンタルサーバー | ヘテムル |
| Git管理ツール | SourceTree |
| 言語 | PHP |





# おおまかな流れ

1. **事前準備**
    1. 【ヘテムル】ドメイン設定
    1. 【ヘテムル】SSHログイン
1. **GitHub用SSHキーの設定**
    1. 【ヘテムル】GitHub用のSSHキーを生成
    1. 【GitHub】公開鍵を登録する
1. **手動でpull**
    1. 【GitHub】リポジトリ作成
    1. 【ヘテムル】手動でリポジトリをプル
1. **自動デプロイ**
    1. 【SourceTree】ローカルにリポジトリをクローン
    1. 【GitHub】Webhookを登録する
    1. 【ローカル】 編集してpush





# 事前準備



## 【ヘテムル】ドメイン設定

ヘテムルで最初から用意されているドメインだと、サブドメインが登録できませんでした(´；ω；｀)
ちょうど使ってなくて解約したけどもうしばらく使えるドメインがあったので、今回はそれを使ってみます。



**▼ ムームードメインでドメインを取得している場合は、ネームサーバーをムームーDNSに変更します。**
![ネームサーバ設定変更](https://qiita-image-store.s3.amazonaws.com/0/186046/90daaa0c-904e-2f1e-02d5-b1a0272bd618.png)



**▼ ヘテムル側でドメイン設定をします。**
![独自ドメインの登録](https://qiita-image-store.s3.amazonaws.com/0/186046/a8d0c620-5123-4302-9d36-2456b9a0d608.png)



**▼ サブドメイン（develop）を作成します。**
![サブドメインの作成](https://qiita-image-store.s3.amazonaws.com/0/186046/b6973e37-98f5-e01c-83e3-64d7240bb9d3.png)






## 【ヘテムル】SSHログイン

こちらの記事に詳しく書いたので、割愛します。
:point_right_tone2: [Qiita > 初心者がGitHubからヘテムルに手動pullするまでのお話](http://qiita.com/HitomiHoshisaki/items/4c892b97ac9ee6b97e3b)





# SSHキーの設定



**▼ 公開鍵とは**

公開鍵？秘密鍵？SSHキー？SSHアカウントのサーバーとかパスワードとは違うの？？？
慣れない言葉が飛び交っていまいち分かりにくかったのですが、さくらさんの説明が分かりやすかったです！以下抜粋。

> 公開鍵認証方式でログインするには鍵が2つ必要です。
> パソコン側に置く秘密鍵ファイルと、サーバー側に置く公開鍵ファイルです。
>
> 秘密鍵ファイルは人に知られてはいけません。
> 公開鍵ファイルは、人に知られても良い(公開できる)ファイルです。
> この2つのファイルが揃って初めて公開鍵認証によるログインが可能になります。
>
> 公開鍵認証では、sshのログイン時に使ったパスワードの代わりに「パスフレーズ」を使用します。
> サーバーへログインするパスワードと似たようなもので、自分が決めた文字列を設定できますが、これはサーバーへログインするためのものではなく、秘密鍵にアクセスするための秘密の文字列です。
>
> :point_right_tone2: [さくらのナレッジ > 「よく分かる公開鍵認証」～初心者でもよくわかる！VPSによるWebサーバー運用講座(2)](http://knowledge.sakura.ad.jp/beginner/3543/)





## 【ヘテムル】GitHub用のSSHキーを生成

リモートに鍵を置くって危なくないの！？
とオロオロして2〜3日調べてたんですが、どーにもこーにもうまくいかない。
なので、ここではいったん諦めてリモートに鍵を置く方法で進めます。
どなたか解決策知ってたら教えてくださいm(_ _)m



**▼ 新しいSSH鍵を生成する。**
:point_right_tone2: [GitHub Help > 新しいSSH鍵を生成してssh-agentに追加する](https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/)

```:リモート
$ ssh-keygen -t rsa -f id_rsa_github

# 最後のファイル名は自由です
# 鍵の保存先を聞かれるので、デフォルトのままEnterする
# パスフレーズを聞かれるので、空のまま2回Enterする
```



**▼ 【リモート】Hostの指定をする**
:point_right_tone2: [Developers.IO > 【メモ】githubの複数アカウントにSSH接続するための設定手順](http://dev.classmethod.jp/tool/github-ssh-sub-account-setting/)

```:リモート
$ vi ~/.ssh/config                       # viが立ち上がる
i                                        # INSERTモードに変更

Host github-【GitHubユーザー名】
  User git
  Port 22
  HostName github.com
  IdentityFile ~/.ssh/id_rsa_github      # 自分で設定した鍵のファイル名
  TCPKeepAlive yes
  IdentitiesOnly yes

ESCキー                                   # コマンドモードに戻る
ZZ                                       # 上書き保存し、viを終了
```





## 【GitHub】公開鍵を登録する

:point_right_tone2: [Qiita > gitHubでssh接続する手順~公開鍵・秘密鍵の生成から~](http://qiita.com/shizuma/items/2b2f873a0034839e47ce)



**▼ 公開鍵をクリップボードにコピー。**

リモートで直接コピーができなかった(なにかやり方があるのかもしれないが)ので、
ローカルに一度ダウンロードしてからコピーしました。

```:ローカル
$ pbcopy < ~/.ssh/id_rsa_github.pub      # 自分で設定した鍵のファイル名.pub
```



**▼ GitHubのSettingsメニューから登録。**
![Add SSH Key](https://qiita-image-store.s3.amazonaws.com/0/186046/0833f285-0816-930b-4b7b-79a27ab97cd5.png)

Titleは分かりやすければ何でもいいらしい(画像はhetemlになってるけど、GitHubとかのがいいだろう)。
Keyは先ほどクリップボードにコピーしたものを貼り付けるだけ！



**▼ 無事登録できました！**
![SSH Keys](https://qiita-image-store.s3.amazonaws.com/0/186046/cf96502a-b729-485c-ca4a-664bff8d3d85.png)




**▼ 接続を確認する。**

```:リモート
$ ssh -T github-【GitHubユーザー名】
# なんかyes/no聞かれたら'yes'とEnter
```
↓こんなふうに返ってきたら成功です☆

```:リモート
Hi 【ユーザー名】! You've successfully authenticated, but GitHub does not provide shell access.
```





# 手動でpull

## 【GitHub】リポジトリ作成

割愛。





## 【ヘテムル】手動でリポジトリをプル

```:リモート
$ cd ~/web/xxxxx.xx/master
$ git init
$ git remote add origin git@github-【GitHubユーザー名】:【GitHubユーザー名】/【リポジトリ名】.git
$ git pull origin master
```

うまいこと動きました！





# 自動デプロイ



## 【ローカル】自動デプロイのプログラムを作る

こちらの記事を参考に、改造させていただきました！
:point_right_tone2: [よしあかつき.net > GitHubにプッシュしたらブランチ毎に自動デプロイする仕組みをXサーバー上に作ってみた](https://yosiakatsuki.net/blog/github-auto-deploy/)

```php:_deploy.php
<?php

/*
 * ▼ このファイルの使い方
 * GitHubの Settings > Webhooks に以下のように設定する
 * Payload URL:		http://xxxxx.heteml.net/_hook.php
 * Content type:	application/json_decode
 * Secret:			$SECRET_KEY
 * Which events...:	Just the push event.
 */

# ──────────────────────────────
# 設定(基本的にここだけ環境に合わせて変更する)
# ──────────────────────────────

# ログファイル定義
$LOG_FILE = dirname(__FILE__).'/_hook.log/hook.log';

# エラーログファイル定義
$LOG_FILE_ERR = dirname(__FILE__).'/_hook.log/hook-error.log';

# GitHubに設定するパスワード的な物(お好きな文字列)
$SECRET_KEY = 'xxxxx';

# git pullしたいブランチ(配列)
$BRANCHS = array('develop','master');

# ──────────────────────────────

# 全てのHTTPリクエストヘッダを取得
$header = getallheaders();

# POSTの生データを取得
$post_data = file_get_contents( 'php://input' );

# ハッシュ値を生成
$hmac = hash_hmac('sha1', $post_data, $SECRET_KEY);

# 'X-Hub-Signature'はGitHubのWebhooksで設定したSecret項目
# リクエストヘッダで受け取ったSecretとconfig.phpの$SECRET_KEYが同一であれば認証成功
if ( isset($header['X-Hub-Signature']) && $header['X-Hub-Signature'] === 'sha1='.$hmac ) {

	# 受け取ったJSONデータ
	$payload = json_decode($post_data, true);
	
	foreach ($BRANCHS as $branch) {
		
		# ブランチ判断
		if($payload['ref'] == 'refs/heads/'.$branch){
			
			# 各サイトのブランチフォルダに移動
			chdir($payload['repository']['name'].'/'.$branch);
			
			# pull実行
			exec('git pull origin '.$branch.' 2>&1', $output, $return);
			
			# ログ記録
			file_put_contents($LOG_FILE,
				date("[Y-m-d H:i:s]")." ".
				$_SERVER['REMOTE_ADDR']." ".
				$payload['repository']['name']."/".$branch." ".
				$payload['commits'][0]['message']." ".
				$output[0]." ".$return."\n",
				FILE_APPEND|LOCK_EX
			);
		}
	}

# 認証失敗
} else {
	
	# エラーログ記録
	file_put_contents($LOG_FILE_ERR,
		date("[Y-m-d H:i:s]")." ".
		$_SERVER['REMOTE_ADDR']." 認証失敗"."\n",
		FILE_APPEND|LOCK_EX
	);
}
?>
```

**▼ ハマったところメモ**
各サイトのブランチフォルダに移動するところで、
どうしても`exec('cd ...')`がうまくいきませんでした。
調べたらphpで`cd`は使えないらしい。
`chdir()`を使うことにしたら解決しました。

それでもどうもうまいことカレントディレクトリの変更ができない…
`_hook.php`自体をwebディレクトリ直下に移動したら動きました！





## 【GitHub】Webhookを登録する



**▼ Webhooksの設定画面を開きます。**
![Webhooks](https://qiita-image-store.s3.amazonaws.com/0/186046/c17b073d-c039-cc4e-b62d-c58c5f87697f.png)



**▼ こんな感じに設定。**
ヘテムルで最初から用意されているドメインを使うとよい。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/186046/163409ed-2796-8894-8fdd-c23695a59d33.png)





## 【ローカル】 編集してpush

ローカルでファイルを編集してmasterブランチにpushすると、
リモートのファイルにも反映されるのが分かると思います。