Git のフックを利用した本番環境適用の仕組みや post-update などのスクリプトの書き方、必要となる SSH 接続の設定方法を説明します。
GitHubの場合はこちら
参考: GitHub Actions を利用した本番環境適用(デプロイ)の方法
Git のフックを利用したデプロイの仕組み
Git には フック【hooks】という仕組みがあり、Git に対するアクションをトリガーとしてなんらかのスクリプト処理を行うことができます。
例えばリモートリポジトリ(中央リポジトリ)に修正コードをpush
したタイミングで本番環境にもその修正コードを自動で反映させる(デプロイ)ということもできます。
基本的には、master
ブランチへのpush
で本番環境へ、develop
ブランチへのpush
でステージング環境へデプロイするフックを作成します。
下図はmaster
ブランチから本番環境へのデプロイを表しています。
origin master
へのpush
(①)が完了すると、リモートリポジトリのフックスクリプトが動作します(②)。
フック処理では本番環境に SSH 接続し、本番環境側からorigin master
をpull
するよう記述します(③)。pull
が成功すると本番環境のワーキングディレクトリが更新され、本番用のソースコード等がここへ配置されます。
ワーキングディレクトリの一部をドキュメントルートに指定することにより、利用者は最新の環境をブラウザでアクセスできるようになります。
フックスクリプトの書き方
フックのスクリプトは.git/hooks
配下にあります。
フックスクリプトには色々な種類があり、Git へのアクションにおける様々なタイミングでスクリプトを走らせることが可能ですが、デプロイに関しては以下のスクリプトを利用するのが良いでしょう。
post-receivepush
処理が終了した後で1回呼び出されます。
引数はありませんが、push
された参照のリストを標準入力から受け取ることができます。
このスクリプトではpush
処理を中断させることはできませんが、クライアント側ではこのスクリプトが終了するまで接続を切断できません。
このスクリプトが出力する標準出力の内容はクライアントに返されます。
post-updatepush
処理が終了した後で1回呼び出されます。
実際に更新されたすべてのref
の名前を可変数の引数で受け取ります。
このスクリプトではpush
処理を中断させることはできませんが、クライアント側ではこのスクリプトが終了するまで接続を切断できません。
このスクリプトが出力する標準出力の内容はクライアントに返されます。
下記は post-update によるフックスクリプトの記述例です。
#!/bin/sh
# 基本的に複数のブランチが同時に更新されることはないため、第一引数をチェックする
if [ $1 = "refs/heads/master" ]; then
echo "deploy production"
# GIT_DIR 環境変数が優先されるため、--git-dirでディレクトリを明示指定する
ssh production "cd /path/to && git --git-dir=.git pull origin master"
elif [ $1 = "refs/heads/develop" ]; then
echo "deploy staging"
ssh staging "cd /path/to && git --git-dir=.git pull origin develop"
fi
# リポジトリがHTTP公開の場合に必要(これがないと最新の情報をpullできない)
exec git update-server-info
上記の例では SSH 接続を簡略化するために、.ssh/config
ファイルを事前に設定しています。
Host production
Hostname production.myserver.com
User ec2-user
IdentityFile /path/to/keys/production.pem
Host staging
Hostname staging.myserver.com
User ec2-user
IdentityFile /path/to/keys/staging.pem
本番環境サーバに SSHD を設定する
デプロイはリモートリポジトリサーバが修正コードを適用する側(本番環境)のサーバに SSH で接続し、git pull
することで行います。
したがって本番サーバやステージングサーバ側が SSH 接続を受け入れるよう設定する必要があります。
具体的には SSHD(SSH デーモン) を起動し、22 番ポート(変更可能)を開けるという手順になります。
SSHD の設定(Windows Server)
Windows Server にはデフォルトで SSHD が入っていませんのでインストールから必要になりますが、Git for Windows には SSHD も含まれていますのでこれを利用しましょう。
ちなみに Git for Windows は以下の URL からダウンロードできます。
https://gitforwindows.org/
まずは git bash を起動し、SSHD が利用する var フォルダを作成します。
>mkdir /var
>mkdir /var/empty
>mkdir /var/log
>touch /var/log/lastlog # SSH 接続のログファイル
sshd_config ファイルを設定します。
パスワードを聞いてくるとそこでスクリプトがストップしてしまいますので、ここでは公開鍵認証のみ設定します。
LogLevel を DEBUG にしておくことで、エラー発生時の原因究明に役立つログを出力してくれます。
>cd /etc/ssh
>vim sshd_config
・・・
PubkeyAuthentication yes # 公開鍵による認証あり
PasswordAuthentication no # パスワード認証なし
LogLevel DEBUG # デバッグログ
・・・
次に SSH ポートを開放します。
コントロールパネルより、Windows ファイアウォールの「詳細設定」画面を開きます。
(セキュリティが強化された Windows ファイアウォール)
受信規則から新しい規則を作成します。
ウィザードにしたがってそれぞれ入力していきます。
規則の種類:ポート
プロトコルおよびポート:TCP、特定のローカルポート 22
操作:接続を許可する
プロファイル:ドメイン、プライベート、パブリック
名前:SSH
受信規則が作成できました。
SSH 接続に IP アドレスアクセス制限をかける場合は、作成した規則をダブルクリックし、スコープタブを開きます。
「これらの IP アドレス」を選択し、許容するアドレスを追加します。
SSHD の起動には sshd というユーザが必要です。
セキュリティの観点からデーモンプロセスを root 権限で起動しないための特権分離オプションにより、SSHD は sshd ユーザによって起動されます。
sshd ユーザが存在しない場合は SSHD 起動時に以下のエラーが発生します。
Privilege separation user sshd does not exist
sshd ユーザを追加する手順は以下の通りです。
スタートメニューから「Windows 管理ツール」→「コンピューターの管理」を開き、左メニューの「ローカルユーザーとグループ」→「ユーザー」を選択します。
上部メニューの「操作」から「新しいユーザー」をクリックします。
ユーザー名を sshd としてユーザーを作成します。
パスワードは無期限の方が運用が楽かなと思います。
最後に SSHD を起動します。
>/user/bin/sshd.exe
Windows にリブートがかかった場合にも SSHD が起動するようスタートアップに登録しておくと良いでしょう。
スタートアップフォルダは以下になります。
C:/ProgramData/Microsoft/Windows/Start Menu/Programs/Startup
なお、Git の SSHD を利用しない場合は、以下の Windows 向け OpenSSH を利用すると良いでしょう。
こちらはサービス化されるので Windows にリブートがかかった場合にも自動で再起動されます。
なお、デフォルトの sshd_config の場所は以下になります。
C:/ProgramData/ssh/sshd_config
公開鍵の登録
SSH キー(公開鍵と秘密鍵)を作成します。
SSH キーの作成は SSH 接続する側でもされる側でもどちらで作成しても良いですが、SSH 接続側で秘密鍵(id_rsa
)ファイルが必要となりますので、取り扱いにご注意ください。
以下は RSA 方式の場合になります。
※ssh-keygen
コマンドを利用するには Git をインストールする必要があります。
>ssh-keygen -t rsa -b 4096
キーの保存先やパスフレーズの設定を聞かれますが、そのままEnter
を繰り返したデフォルト設定で大丈夫です。
なお、キーの保存先はデフォルトでは以下の場所にid_rsa
、id_rsa.pub
の名前で保存されますので、もしすでに作成しているキーが存在している場合は退避しておいてください。
Windows
%UserProfile%\.ssh
Linux
/home/{ユーザー}/.ssh
作成された公開鍵(id_rsa.pub
)を SSHD へ登録して完了です。
下記ファイルにid_rsa.pub
(RSA方式の場合)の内容を追記します。
%UserProfile%/.ssh/authorized_keys
ssh-rsa AAAflkajeflaj・・・
これで秘密鍵(id_rsa
)を使用してSSH 接続することができるようになりました。
この設定ファイルの場所やファイル名は sshd_config の AuthorizedKeyFile ディレクティブで変更が可能です。
AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
SSHD の設定(Linux)
AWS など大抵の VPS では、すでにインストール済みになっているかと思いますが、まずは openssh-server をインストールし起動します。
>dnf install openssh openssh-server # CentOS
>apt install openssh-server # Ubuntu
>systemctl start sshd # sshdの起動
>systemctl enable sshd # 自動起動ON
セキュリティの観点から root ユーザによる SSH 接続やパスワード認証を禁止します。
>vi /etc/ssh/sshd_config
# rootログイン禁止
#PermitRootLogin yes
↓
PermitRootLogin no
PasswordAuthentication no # パスワード認証を禁止する
>systemctl restart sshd # sshdの再起動
SSH 接続するポートを開放します。
(>firewall-cmd --remove-service=ssh --zone=public --permanent # 設定の削除)
>firewall-cmd --add-service=ssh --zone=public --permanent # ポートの開放
>firewall-cmd --reload # 設定をリロード
>firewall-cmd --list-all # 設定確認
SSH 接続に IP アドレスアクセス制限をかける場合は、以下のコマンドを実行します。
>firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="許可するIPアドレス" service name="ssh" accept"
>firewall-cmd --reload
>firewall-cmd --list-all # 設定確認
設定ファイル(/etc/firewalld/zones/public.xml
)を直接編集することもできます。
>vi /etc/firewalld/zones/public.xml
<?xml version="1.0" encoding="utf-8"?>
<zone>
<short>Public</short>
<description>For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description>
<service name="dhcpv6-client"/>
<service name="cockpit"/>
<service name="http"/>
<service name="https"/>
# ここから
<rule family="ipv4">
<source address="許可するIPアドレス"/>
<service name="ssh"/>
<accept/>
</rule>
# ここまでを追記
</zone>
公開鍵の登録
SSH キー(公開鍵と秘密鍵)を作成します。
SSH キーの作成は SSH 接続する側でもされる側でもどちらで作成しても良いですが、SSH 接続側で秘密鍵(id_rsa
)ファイルが必要となりますので、取り扱いにご注意ください。
以下は RSA 方式の場合になります。
※ssh-keygen
コマンドを利用するには Git をインストールする必要があります。
>ssh-keygen -t rsa -b 4096
キーの保存先やパスフレーズの設定を聞かれますが、そのままEnter
を繰り返したデフォルト設定で大丈夫です。
なお、キーの保存先はデフォルトでは以下の場所にid_rsa
、id_rsa.pub
の名前で保存されますので、もしすでに作成しているキーが存在している場合は退避しておいてください。
Windows
%UserProfile%\.ssh
Linux
/home/{ユーザー}/.ssh
作成された公開鍵(id_rsa.pub
)を SSHD へ登録して完了です。
下記ファイルにid_rsa.pub
(RSA方式の場合)の内容を追記します。
/home/{ユーザ名}/.ssh/authorized_keys
>cd /home/{ユーザ名}/.ssh
>mv id_rsa.pub authorized_keys
>cat id_rsa.pub >> authorized_keys # すでにauthorized_keysが存在する場合は追記
>chomod 600 authorized_keys
これで秘密鍵(id_rsa
)を使用してSSH 接続することができるようになりました。
この設定ファイルの場所やファイル名は sshd_config の AuthorizedKeyFile ディレクティブで変更が可能です。
AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
SSH 接続してみましょう
秘密鍵(id_rsa
)を SSH 接続する側に持って行きます。
SSH 接続してみましょう。
>ssh -i /path/to/keys/id_rsa ec2-user@11.22.33.44 # ログインユーザ名@サーバのIPアドレス
>ssh -i /path/to/keys/id_rsa ec2-user@myserver.com # ログインユーザ名@ドメイン名
秘密鍵は/path/to/keys
に配置しています。
ログインユーザ名とサーバのIPアドレスを指定することで SSH 接続できました。
この辺りのオプション設定が面倒であれば、コンフィグファイルにあらかじめエイリアスを設定することができます。
Windows
%UserProfile%/.ssh/config
Linux
/home/{ユーザ名}/.ssh/config
Host SSH-Server
StrictHostKeyChecking no # know_hostsへの登録等の確認を省略
Hostname myserver.com
User ec2-user
IdentityFile /path/to/keys/id_rsa
# 複数設定できます
Host TestRep
Hostname github.com
User git
IdentityFile /path/to/keys/id_rsa
なお、自動デプロイなどのスクリプトから SSH 接続する場合、確認メッセージによって途中で動作が止まらないよう config の設定にて StrictHostKeyChecking を no にしておく必要があります。
ssh
コマンドを実行して SSH 接続します。
>ssh SSH-Server
GitHub へ SSH 接続する場合
GitHub へ SSH 接続してgit clone
等を行う場合は、秘密鍵を GitHub へ登録します。
当該リポジトリの上部メニュー「Settings」より左メニュー「Deploy keys」をクリックし、「Add deploy key」ボタンをクリックします。
Title にタイトルを入力し、Key に秘密鍵(id_rsa)の内容をコピーします。
コピーする内容はヘッダ部(—–BEGIN OPENSSH PRIVATE KEY—–など)やフッター部も含めてコピーします。
Allow write access にチェックを入れることで、git push
が可能となります。
チェックを入れない場合は参照のみとなります。
「Add key」をクリックして登録完了です。
ちなみにgit cloneする場合は、以下のようなコマンドになります。
config でキーの場所等を設定済みであれば、2行目のようにコマンドが簡略化できます。
>git -c core.sshCommand="ssh -i /path/to/keys/id_rsa" clone git@github.com:yanox2/TestRep.git
>git clone TestRep:yanox2/TestRep.git
以上です。
SSH 接続のまとめ
設定元 | SSH 接続 | 設定ファイル(設定メニュー) | 内 容 |
---|---|---|---|
自環境 | する側(ssh) | .ssh/config | 秘密鍵(id_rsa) |
自環境 | される側(sshd) | .ssh/authorized_keys (sshd_config) | 公開鍵(id_rsa.pub) |
GitHub | される側(git cloneなど) | (repository)Settings > Deploy keys (for repository) (user)Settings > SSH and GPG keys (for user) | 公開鍵(id_rsa.pub) |
参考: Git を利用した開発環境・テスト環境・本番環境の構成
参考: Git ワークフロー(ブランチモデル)とその手順
参考: Git コンフリクトの解消
参考: git push を Chatwork や Slack へ通知する方法
コメント