簡易デプロイツールを「Git+シェルスクリプト」で実装してみた
こんにちは、okutani(@okutani_t)です。前回、こんな記事を書きました。
「git pushでデプロイをかんたんにおこなえる環境を構築する」といった内容の記事です。
この方法でもよいのですが「本番環境にbareリポジトリをわざわざ作るのがめんどう」&「bareリポジトリはGithubだけで良い」という方向けに、別の方法を考えました。『Git + シェルスクリプト』でデプロイする方法です。
デプロイ方法なんかで検索してみると、Githubにpush時、Jenkinsなどでhookを受け取りデプロイをおこなう方法がたくさん出てきますよね。Capistranoなんてデプロイツールもあるそうです。
JenkinsなどのCIや、Capistranoといったツールが使えればそれでも良いですが、以前務めていた現場では残念ながらCIが無い環境だった(Capistranoは使い方分からない)ので、別の方法を模索していました。
というわけで今回、『Git + シェルスクリプト』でデプロイできるシェルスクリプトを書いてみました。
今回、作成したデプロイをおこなうシェルスクリプトの内容は、以下のとおり。
- SSHでサーバーにログイン
- デプロイ場所まで移動
- プロジェクトが存在しなければgit clone、あればgit pull
なお、サーバーにGitがないと動作しないので、事前に導入しておきましょう。
導入するには「参考CentOS7に最新のGitを導入する方法 | vdeep」「参考エックスサーバーにGitを導入する手順 | vdeep」あたりを参考にしてください。
レンタルサーバーでもSSHが使えるプランであれば、たいていGitは導入できるかと思います。
同じく、「参考GitHubの登録手順。SSH設定&リポジトリをclone, pushまで解説 | vdeep」を一読してSSH鍵の接続設定を終わらせておく必要があります。bitbucketでも、同様の手順で本記事の内容のデプロイ方法が利用できるので試してみてください。
では、実際にシェルスクリプトを使ってプロジェクトをデプロイしてみましょう!
スポンサーリンク
ssh-addで鍵を登録
本番環境でgit pullをおこなうのに、ローカルで利用してる鍵情報が必要なのでssh-agentを利用します。
なお、WindowsやLinuxの場合は、上記コマンドの前にssh-agentを起動しておく必要があります。Macでは自動で立ち上がってるのでそのままでOKです。
$ eval `ssh-agent`
これをしておかないと「Could not open a connection to your authentication agent.」と怒られてしまうので注意してください。
さらに、Windows・linuxではシェル再起動時にssh-agentが終了してしまうため、「~/.bashrc」などに次のコードを書いておくと自動で立ち上がって便利です。
eval `ssh-agent` > /dev/null 2>&1
ssh-add ~/.ssh/id_rsa > /dev/null 2>&1
ssh-agent自動起動の設定はぐぐればたくさん出てくるので、上記の方法が嫌な人は自分で設定してみてください。ちなみに、「 > /dev/null 2>&1」をつけることで、シェル起動時に表示される文字列を隠しています。
ssh-addコマンドで鍵を登録。※Macの人はここから作業しましょう
$ ssh-add ~/.ssh/id_rsa
Identity added: /Users/username/.ssh/id_rsa (/Users/username/.ssh/id_rsa)
下記で登録した鍵情報の確認。
$ ssh-add -l
これでSSH接続の準備が整いました。
デプロイをおこなうシェルスクリプトを作成
場所はどこでもいいので、次のようにシェルスクリプトを作成します。私は分かりやすいようにプロジェクトのルートディレクトリに配置しています。
#!/bin/bash
#############ここから#############
# デプロイしたいディレクトリの場所
deploy_path=dir_path
# デプロイするプロジェクトの名前
proj_name=proj_name
# リモートリポジトリのURL
remote_path=git@github.com:okutani-t/proj.git
# デプロイするブランチ
branch=master
# 本番環境へのSSHログイン情報(ユーザ名@ホスト名)
host=user@host
#############ここまで#############
# yes/noで応答
function confirm () {
echo -n $1
read answer
case `echo $answer | tr y Y` in
Y*)
;;
*)
echo "Bye."
exit
;;
esac
}
# 本当にデプロイするか確認
confirm "Is it OK to deploy? [y/n]"
# -AでSSH鍵をサーバーでも利用
# StrictHostKeyCheckingで初SSH接続時の[yes/no]を無視
ssh -A -o StrictHostKeyChecking=no ${host} "
# Gitがあるか確認
if ! type 'git' > /dev/null 2>&1; then
echo 'git not found...'
exit 1
fi
# デプロイ場所が無かったら作成
if [ ! -e ${deploy_path} ]; then
confirm 'Is it OK to create '${deploy_path}' dir?[y/n]'
mkdir -p ${deploy_path}
fi
cd ${deploy_path}
# プロジェクトのディレクトリがあるか確認
# なければclone、あればpullをおこなう
if [ ! -e ${proj_name} ]; then
git clone ${remote_path} ${proj_name}
echo 'cloning success!'
else
cd ${proj_name}
# pullもしくはfetch&reset --hardを使う
# 競合を起こさないよう、強制的に最新のリモートリポジトリに合わせる
git fetch origin
git reset --hard origin/${branch}
# git pull origin ${branch}
echo 'deployment success!'
fi
"
設定箇所は「ここから」「ここまで」内の以下の項目です。
- deploy_path
- proj_name
- remote_path
- branch
- host
デプロイしたいディレクトリの場所
デプロイするプロジェクトの名前
リモートリポジトリのURL
デプロイするブランチ
SSHをおこなうhost(user@hostの形)
横着してひとつのファイルに設定項目をまとめて書いてますが、別ファイルで管理してもいいかと思います。
やってることは、ローカルにある秘密鍵を持ってSSHで本番環境へ接続し、本番環境にプロジェクトがなければgit clone、あればgit pullをおこないます。
ただ、git pullだと競合する場合がなきにしもあらずなので、git fetch、git resetで強制的にリモートリポジトリの最新コミットに合わせています。ここら辺はお好みで選択してください。
host部分は、「~/.ssh/config」でホストへのSSHを管理していれば、そちらを使ってOKです。「host=sakura」のように短く記述できますね。
では、実際に作成したシェルスクリプトを実行してみます。
デプロイの実行
実行権限を設定します。
$ chmod +x deploy.sh
次のとおり実行。
$ ./deploy.sh
Is it OK to deploy? [y/n]y
Cloning into 'プロジェクト名'...
cloning success!
このとおりサーバーにログイン後、git cloneをおこなってデプロイをおこなうことができました。
てきとうに変更をコミット&GitHubにプッシュ後、再度deploy.shを実行してみます。
$ ./deploy.sh
Is it OK to deploy? [y/n]y
From github.com:okutani-t/hoge
f87d5cf..5ae1784 master -> origin/master
HEAD is now at 5ae1784 hoge commit
deployment success!
サーバーにデプロイされたファイルを確認し、変更したコミットが反映されているか確認してみてください。
簡易的ではありますが、Git+シェルスクリプトを使ってデプロイをおこなうことができました。
まとめ
今回は「Git+シェルスクリプト」でデプロイをおこなうスクリプトを書いてみました。
利点は「小回りが利く」「CIがいらない」「自分のタイミングでデプロイできる」といった点でしょうか。
欠点は「プロジェクトごとにdeploy.shファイルが増える」「リモートリポジトリpush時に自動でデプロイのようなことができない」あたりですかね。
GitHubのHookなんかをうまく使えば実装できそうですが、とりあえずこのへんまでにしておきます。
すでにCIを利用して自動デプロイしてる方には参考にならん記事ですが、CIがなくて手軽にデプロイを自動化したい方の参考になれば幸いです(あとCapistranoだれかおしえt)。
もっと良い書き方があったら、Twitterとかコメントで共有していただけると嬉しいですm(_ _)m
Web開発のお仕事を募集しています
フリーランスのエンジニアとして、Webシステム開発のお仕事依頼を随時募集しています(現在の業務量によってお受けできない場合もあります)。
「Ruby on Rails」「JavaScript(jQuery, Reactなど)」「HTML + CSS」を用いたシステム開発、「Heroku」等を用いたサーバー構築・運用、「Git」や「GitHub」を利用したソーシャルコーディングなどに対応しています。
ご依頼を検討している方は、下記リンク本ブログからのお問い合わせ、もしくはokutaniのポートフォリオからご連絡ください。
LINKお問い合わせ
スポンサーリンク