GitHubにPushした時に本番環境に自動でデプロイする仕組みを作る

GithubにPushした時に、わざわざ本番サーバーにアクセスしてデプロイするのが面倒なので、今回はpush時に自動でデプロイする仕組みを作っていく。

環境

  • 開発環境(Local) Mac 10.14.6
  • git version 2.20.1
  • 本番環境 CentOS 7

今回目指すべき自動デプロイについて

自動デプロイをする方法だが、今回は「本番環境にgitとwoking directoryを設置して、そのgitに対してデプロイ。その後、本番環境内で本番環境を整える」という方法を取る。

gitにはHook「Git - Git フック」という便利な機能がある。Hookを使うことで、「もし、ローカルからのgit push等でリポジトリが更新された時に、この処理をしてね」という風に、gitが自動で処理をする仕組みを作ることができる。

ネットの記事を読むと、本番のディレクトリ(例えば/var/www/html/exapmle/)にgit環境を作っている方もいるが、なるべく本番環境には余分なファイルを載せるのはセキュリティの観点からも好ましくなく、今回紹介する方法が望ましい。

自動デプロイを実現するための手順

以下は、自動デプロイを作るための方法を分かりやすく紹介する。

前提として、以下の2つはすでに行なっているものとする。

  • GitHubの環境が整っている(GitHubにgit push等ができる)
  • 本番サーバーにsshでログインできる。

それでは、解説に移る。

1,本番サーバーにgitとデプロイ用の一時ディレクトリを作成

まずは、本番サーバーにgitとデプロイのための一時ディレクトリを作る。

最初に本番サーバーにgitをインストールしよう。

sudo yum install git
git --version

これでgitのバージョンが表示されたらOK.

次にgitのリポジトリ用のディレクトリと、そのリポジトリからcheckoutで一時的にプロジェクトのファイルを保管するためのディレクトリを作成する。

例として、本番サーバーにログインしているユーザー名をtanakaとして、ホームディレクトリを/home/tanaka/とすると、以下のコマンドを実行する。

sudo mkdir -p /deploy/tmp/
sudo chown tanaka:tanaka /deploy/tmp/
sudo chmod g+w /deploy/tmp/

mkdirはオプションに-pを付けることで、サブディレクトリも一緒に作成してくれる。

参考:【 mkdir 】 ディレクトリを作成する | 日経クロステック(xTECH)

次にgitのリポジトリ用のディレクトリを作成する。今回のプロジェクト名はexampleとする。

sudo mkdir -p /deploy/git/example.git
cd /deploy/git/example.git
sudo git init --bare

次にgitリポジトリのパーミッションを設定する

cd /deploy/git/example.git
sudo chown -R tanaka:tanaka ./
sudo chmod -R g+rwX ./
sudo find . -type d -exec chmod g+s '{}' +
sudo git config core.sharedRepository group

2,gitのHook処理を書く

次に本番サーバーのgitリポジトリが更新された時に行うHook処理を書く。

cd /deploy/git/example.git/hooks
sudo vi post-receive

viを開いたら、以下のように書く。

#!/bin/sh

# 本番ディレクトリ
TARGET="/var/www/html/example"
# 一時ディレクトリ
TEMP="/home/tanaka/deploy/tmp/example"
# git リポジトリ
REPO="/home/tanaka/deploy/git/example.git"

mkdir -p $TEMP

#一時ディレクトリに対してcheckoutを行う
git --work-tree=$TEMP --git-dir=$REPO checkout -f

# 本番ディレクトリを一旦削除して、その後一時ディレクトリを本番ディレクトリに移す
cd /
rm -rf $TARGET
mv $TEMP $TARGET

sudo chown -R apache:apache $TARGET

色々な書き方があるが、今回はシンプルな書き方にしている。

最後の行のようにHook処理内でsudoで実行したい時があると思うが、初期設定のままだとsudo実行時にパスワードを要求されるので、Hookでは処理ができない。

このような場合は、visudoを実行する。visudoを実行すると設定ファイルが開くので、そのファイルの末尾に以下の文を追加する。

tanaka  ALL=(ALL) NOPASSWD: /bin/chown

これでtanakaユーザーでsudo chownコマンドをパスワードなしで行えるようになる。

3,ローカルで本番サーバーのgitにpushできるようにする

ローカルのプロジェクトディレクトリに戻って、本番サーバーにgit pushできるようにする。

cd example/.git
vi config

configファイルを開いたら、以下の1文を追加する。

[remote "origin"]
    url = git@github.com:tanaka/example.git
    # 以下を追加
    url = vultr:/home/tanaka/deploy/git/example.git

今回はvultrというサーバーを借りて行っているので、サーバー名やディレクトリ名は変更して使うこと。

これでローカルでgit push origin masterを実行すれば、本番サーバーにも変更が反映されているはず。