BacklogのGitリポジトリからCPIサーバに自動デプロイする

Gitを使ったワークフローで、とてもとまどったのが テストアップまでの工程の長さ、スピードの遅さ です。Gitを使う前までは、作業後DWでチェックインするだけ(ポチっとするだけ)でテストアップが完了していたので「差分を抽出して手動でFTP」という段取りに「ほんとにこれでいいのかな??と」デメリットを強く感じました。作業効率を落としてでも、コードレビューや履歴管理を取り入れるべきなんだろうか、と。

アプリやシステム開発がメインではない、いわゆるWebサイトの構築が主体の場合は、実際にブラウザで表示させた状態でのコンテンツの確認が不可欠。なので弊社でも、ローカル開発サーバとテストサーバを同期し、テストアップ後にコードのチェックを行うというフローを組むことで、テストアップまでの時間をなるべく短縮するようにしてきました。

関連記事:Git以前のワークフロー

一転Gitで管理することになると、リモートリポジトリに作業履歴を登録した後、差分を抽出して手動でテストサーバにFTPしなければ、テストアップの共有ができない、という事に。むむむ。それはあまりにも非効率…。
ということで、リモートリポジトリへのpush(merge)があった場合に、指定するサーバに自動で差分を反映するような仕組み を用意する必要がありました。

環境情報:
・SSHとGitが使えるテストアップ用サーバ(CPI:ACE01)
・GitのWebフックが使えるリモートリポジトリサーバ(Backlog)
・事前にリモートリポジトリの準備ができている前提

自動デプロイの仕組み

リモートリポジトリにある統合ブランチからテストサーバへ自動デプロイをする方法として、JenkinsなどのCIサーバを使うやり方もありますが、システム的なテストの自動実行が不要なので、テストサーバに設置したPHPをキックして、Gitリポジトリを同期する方法を取りました。

自動デプロイの全体像

デプロイの工程は次のようなイメージです。

  1. 初回のみ手動でSSHをつなぎ、CPIで`git clone`を実行
  2. Backlogリポジトリの統合ブランチ(master)への`push`(`merge`)でBacklogのWebフックが起動
  3. BacklogのWebフックが、CPIに設置したデプロイ用PHPを起動
  4. PHPによりCPIからBacklogに`git fetch`して最新を取得
  5. CPIで`git checkout`して指定ディレクトリに差分ファイルを設置

プロジェクト着手時に、初回だけ手動でCPIにBacklogのリポジトリをcloneする ようにし、以降は2~5が自動で実行されるようにします。

CPIでSSHが使えるようにする

CPI上のリポジトリにBacklogのリポジトリをクローンするためには、CPIサーバにSSHで接続できる必要があります。まずはCPIでSSHが使えるように、サーバのコントロールパネルから申請をします。

関連記事:CPIのオンラインヘルプ「SSH(鍵認証)」

CPIでSSH鍵ペアを作成

ACE01_2015というサーバの版から、鍵ペアでの認証になり、コンパネ上で鍵ペアの作成ができるようになっています。まずは鍵ペアを作成。(パスワードの入力は回避したいので「パスフレーズ」は空にします)

CPIサーバでSSH公開鍵を作成

「SSH利用開始・利用停止」画面に戻って「鍵公開一覧」に先ほど作成した鍵が追加されていることを確認し、「利用開始する」ボタンをクリックすると、「SSHアカウントはすでに設定済みです。」という表示に切り替わります。これで設定は完了。サーバの所定の場所に自動で公開鍵が設置されます。

CPIサーバでSSH利用の開始

ローカルマシンからSSH接続を確認

CPIでSSHの利用ができるようになったかどうか、ローカルマシンから接続して確認します。ここでは簡単なTeraTermを使う事にしました。TeraTermを立ち上げて、新しい接続を設定します。

TeraTerm:新しい接続画面

項目
ホスト CPIサーバのIPアドレス
TCPポート 公開サーバのポート番号(※1)

※1:【コントロールパネル>お客様情報】内の「SSH/ SFTPポート番号」で確認することができます。

次に「SSH認証」画面で次の項目を入力します。

TeraTerm:SSH接続画面

項目
ユーザ名 「お客様情報」ページ記載の「ユーザID」(※2)
RSA/DSA/ECDSA/ED25519 鍵を使う ラジオボタンを選択
秘密鍵 ダウンロードした秘密鍵ファイルを指定

※2:CPIのサポートページに掲載されていたマニュアル(PDF)では、ここのユーザ名に「ウェブコントロールパネルのユーザーIDを入力してください。」 と記載がありますが、これは

  • 【コントロールパネル>お客様情報】内に記載されている「ユーザID」 です。
  • 【ユーザーポータル】へのログインIDではない

ので、注意が必要です。(実際通らなくて「あれ?」となりました。この辺のややこしいの、なんとかならないですかね…)

[OK] ボタンをクリックすると、ダイアログが閉じて黒い画面に戻ります。「Welcome to FreeBSD!」と表示されていれば、疎通確認完了ですね。

TeraTerm:接続確認完了

初回は手動でSSHをつなぎCPIでclone

初回にCPIとBacklogのリポジトリをつなぐ作業は、手動でCPIにSSHをつないで実行します。

CPIの非公開領域にミラーでclone

クローンするにあたって、次を指定します。

  • [.git]フォルダはサーバの非公開領域(ドキュメントルートの外)に置く(※1)
  • `–mirror`オプションを付けて実ファイルがダウンロードされないようにする

※1:テストサーバなのでベーシック認証を掛ける事が前提ではありますが、念のためドキュメントルートの配下は避けます。

また、CPIから非公開リポジトリ(Backlog)にアクセスする場合、SSHは使えません。なので URLにログイン情報を含めてHTTPSでアクセス します。

例えばクローンするBacklogのリポジトリURLが https://granfairs.backlog.jp/git/test/testrepo.gitの場合、実行するコマンドは次のようになります。

# カレントディレクトリを確認
$ pwd
# クローンする場所まで移動(非公開領域)
$ cd <クローンする場所>
# クローン実行
$ git clone --mirror https://<username>:<password>@granfairs.backlog.jp/git/test/testrepo.git
  • URLに含めるログインIDとPWは、Backlogの該当するプロジェクトにアサインされている(リポジトリの操作が可能な)ユーザのアカウント。(自動デプロイ専用のアカウントを作って、全プロジェクトに自動でアサインされるように設定するといい)
  • ログインIDに「@」が含まれてるとエラーになっちゃう。(どうして「@」を含めたんだ!← ウチ)

FTPでルートディレクトリを確認すると、gitリポジトリ用のディレクトリが新規に追加されていることが確認できます。

クローンしたリポジトリ用ディレクトリ

CPIで初回fetch+checkout

クローンした続きで、最新状態の取得コマンドfetchと差分ファイルの設置コマンドcheckoutの動作を確認します。その際、CPIサーバ上にクローンしたGitリポジトリの場所と、差分ファイルを設置するディレクトリ(=ドキュメントルート)を指定します。

オプション
–git-dir CPIサーバ上のGitリポジトリのディレクトリ(例:/usr/home/userid/test.git)
–work-tree 差分ファイルを設置するディレクトリ(例:/usr/home/userid/html)

コマンドは次の通り

$ git --git-dir=/usr/home/userid/test.git fetch
$ git --git-dir=/usr/home/userid/test.git --work-tree=/usr/home/userid/html checkout -f

CPIサーバのドキュメントルートフォルダにファイルが設置されていることを確認。

自動でファイルが設置される

これでCPIとBacklogのリポジトリをつなぐ初回の作業は完了です。
テストサーバ(CPI)でのgitコマンドについては、次のスライドがとても参考になりました。

参考:Git とスマートリリースで始める チームコラボレーション

自動化する

いよいよ自動化します。設定の手順は次の通り。

  1. 自動化用のPHPスクリプトを、CPIのドキュメントルート配下に設置
  2. Backlogのプロジェクト設定画面で、Gitの「WebフックURL」に「1」のファイルを指定

自動化スクリプトをCPIに設置

自動化用のPHPスクリプトはGitHub(Gist)で素敵なのが公開されていたので、そのまま採用させていただきました(多謝)。

デプロイ自動化PHP:BacklogからCPIへのデプロイスクリプト

ファイル内の設定値を適宜変更して($user_idはCPIの【コントロールパネル>お客様情報】内に記載されている「ユーザID」)、ドキュメントルート配下に設置します。(念のため、推察されにくいディレクトリやファイル名にして設置)

BacklogでWebフックを設定

最後に、BacklogにログインしてWebフックを設定します。

公式情報:Backlogを使いこなそう:Git Webフック

【プロジェクト設定>Git】に表示された一覧から該当するリポジトリの「編集」ボタンをクリック。

Backlogのプロジェクト設定画面

【Gitの設定】画面の一番下にある「WebフックURL」に先ほどCPIに設置した自動化PHPファイルのURLを指定して「リポジトリを更新する」

BacklogのGit設定画面

※テストサーバ(CPI)にベーシック認証を掛けている場合は、URLにログイン情報を含めて指定すればOK。

http://<user_id>:<password>@<url_of_phpfile>

これで全ての設定が完了です!

まとめ

Gitを使う上で、デプロイの自動化は必要不可欠なのでは?と思います。もっと大きい会社さんであれば、ブランチによって複数サーバへ振り分けてデプロイしたり、本番機にも自動で配置したりしているようですね。

参考:大規模サイトでの活用法!nanapiのJenkins利用例

でもデプロイの自動化ってちょっとハードル高いから、それが理由でGitの導入に踏み込めないってこともあるように思います。必要なのは次の2つ。

  • git hookが設定できるリポジトリ管理ツール(Backlog / GitHub / BitBucket / GitLabなど)自前のリポジトリでも頑張ればできる。
  • GitとSSHが使えるWebサーバ

このうちの後者、GitとSSHが使えるWebサーバはまだまだ多くない印象。VPSサーバを借りてWebサーバの環境自体を自作したりとか大ごとになっちゃう。そんな体力持ち合わせてないチームもたくさんあるわけで…。いろいろルールや環境を変えてまで、学習コストを掛けてまでGitってやるべきなの?という問いへの答えは正直まだ出ておらず、私たちもまだまだ実験中です。

2015年12月20日
Gitで管理している一部(=サブディレクトリ)のみがデプロイされるように改良した記事を書きました。 sparse-checkoutでGitのサブディレクトリだけを自動デプロイする