サイズ: 5740
コメント:
|
サイズ: 14643
コメント:
|
削除された箇所はこのように表示されます。 | 追加された箇所はこのように表示されます。 |
行 9: | 行 9: |
* しかし世の中にはもっとカジュアルにWebサイト運用(HTML一枚程度)したいこともしばしば。 * 今回、そんなライトウェイトな要求に対してGitHubで回す&自動デプロイを実施するための仕組みを作ってみた。 |
* しかし世の中にはもっとカジュアル(HTML一枚程度)にWebサイト運用したいこともしばしば。 * 今回、そんなライトな要求に対して!GitHubで回す&自動デプロイを実施するための仕組みを作ってみた。 |
行 16: | 行 16: |
* OSについては古いOS(CentOS6等)ではこの手順では実施できない点に注意。 | * ただし、OSについては古いOS(CentOS6等)ではこの手順では実施できない点に注意。 |
行 23: | 行 23: |
||<#FFFF00> 用途 ||<#FFFF00> ソフトウェア名 ||<#FFFF00> バージョン番号 ||<#FFFF00> 備考 || || OS || `CentOS 7` || `7.7.1908` || SELinuxは有効とする || || Webサーバー || `Apache 2.4` || `2.4.31` || [[https://ius.io/|IUSリポジトリ]] || || Webフック || [[https://github.com/adnanh/webhook|`webhook`]] || `2.6.10` || [[https://snapcraft.io/|スナップクラフト]] || |
* ただし、[[https://snapcraft.io/|スナップクラフト]]固有の問題を回避するためのワークアラウンドだけは別で。 ||<#FFFF00> 用途 ||<#FFFF00> ソフトウェア名 ||<#FFFF00> バージョン番号 ||<#FFFF00> 備考 || || OS || `CentOS 7` || `7.7.1908` || SELinuxは有効とする || || Webサーバー || `Apache 2.4` || `2.4.41` || [[https://ius.io/|IUSリポジトリ]] || || Webフック || [[https://github.com/adnanh/webhook|webhook]] || `2.6.10` || [[https://snapcraft.io/|スナップクラフト]] || || ファイルフック || incron || `0.5.12` || ワークアラウンドのために泣く泣く使用 || |
行 30: | 行 33: |
* GitHubに対して以下の設定を行う。 | * !GitHubに対して以下の設定を行う。 |
行 36: | 行 39: |
* HTTPSオンリーサイトとしてHTTPでの運用は行わない。 | * なおApacheの細かい設定については説明しない。 * 今回のシステムは下記のようなフローとなる。 {{attachment:apache-webhook.png||align="center",width=50%}} = 自作スクリプトの設置 = == ディレクトリ作成 == {{{#!highlight shell numbers=disable sudo mkdir -p /root/.webhook/bin sudo mkdir -p /root/.webhook/run sudo mkdir -p /etc/httpd/libexec sudo restorecon -RFv /root/.webhook sudo restorecon -RFv /etc/httpd/libexec }}} == /root/.webhook/run/activate_id_update-contents == 以下のコマンドを実行してファイルを作成する。 {{{#!highlight shell numbers=disable sudo touch /root/.webhook/run/activate_id_update-contents sudo restorecon -Fv /root/.webhook/run/activate_id_update-contents }}} == /root/.webhook/bin/fecho == {{{#!highlight shell numbers=disable #!/bin/sh : APPEND=no : OUTFILE=- while getopts ao: OPT; do case $OPT in a) APPEND=yes ;; o) OUTFILE=$OPTARG ;; \?) continue ;; esac done shift $((OPTIND - 1)) if [ x"$OUTFILE" = x"" -o x"$OUTFILE" = x"-" ]; then echo $* else if [ x"$APPEND" = x"yes" ]; then echo $* >> "$OUTFILE" else echo $* > "$OUTFILE" fi fi }}} 上記ファイル作成後、下記コマンドを実行すること。 {{{#!highlight shell numbers=disable sudo chmod 0755 /root/.webhook/bin/fecho sudo restorecon -Fv /root/.webhook/bin/fecho }}} == /etc/httpd/libexec/update-contents.sh == {{{#!highlight shell numbers=disable #!/bin/sh cd /var/www/html git pull -q if [ x"$1" = x"refs/heads/master" ]; then git checkout -qf master restorecon -RF . fi }}} |
行 41: | 行 114: |
基本的なセットアップは実施済みであることとする。 | 基本的な(とは何かは議論しない)セットアップは実施済みであることとする。 |
行 45: | 行 118: |
sudo firewall-cmd --add-service=http --permanent | |
行 64: | 行 138: |
== Webhook == | もちろん、本設定は `<Virtual ~>` ~ `</Virtual>` 中で設定してもよい。 == スナップクラフト == |
行 70: | 行 146: |
}}} ※スナップクラフトの有効化のために一度再起動しておくこと。 == Webhook == {{{#!highlight shell numbers=disable |
|
行 73: | 行 155: |
※スナップクラフトの有効化のために一度再起動しておくこと。 === /etc/systemd/system/snap.webhook.webhook.service === ※注意※ {{{#!diff --- /etc/systemd/system/snap.webhook.webhook.service.orig 2019-10-04 15:38:24.368772102 +0900 +++ /etc/systemd/system/snap.webhook.webhook.service 2019-10-06 04:51:03.366711591 +0900 @@ -7,7 +7,8 @@ X-Snappy=yes [Service] -ExecStart=/usr/bin/snap run webhook +EnvironmentFile=-/etc/sysconfig/webhook +ExecStart=/usr/bin/snap run webhook $OPTIONS SyslogIdentifier=webhook.webhook Restart=on-abnormal WorkingDirectory=/var/snap/webhook/2 }}} * webhook起動のための設定オプションの指定ができなかったので、`/etc/sysconfig/webhook`を参照するように改変してみた。 * この変更は更新(`snap refresh`)すると上書きされる可能性があるので注意。 * またこの変更実施直後は `systemctl daemon-reload` を実行すること。 |
※スナップクラフトが稼働してる状態で上記コマンドを実行すること。 === /etc/systemd/system/snap.webhook.webhook.service.d/override.conf === `sudo systemctl edit snap.webhook.webhook.service` コマンドを呼び出して以下の設定を行う。 {{{ [Service] EnvironmentFile=-/etc/sysconfig/webhook ExecStart= ExecStart=/usr/bin/snap run webhook $OPTIONS }}} ※Webhook起動のための設定オプションの指定ができなかったので、`/etc/sysconfig/webhook` を参照するように改変してみた。 |
行 102: | 行 174: |
=== /etc/httpd/conf/hooks.yaml === {{{#!highlight yaml numbers=disable - id: update-contents command-working-directory: "/root" execute-command: "/root/.webhook/bin/fecho" pass-arguments-to-command: - source: string name: "-o" - source: string name: "/root/.webhook/run/activate_id_update-contents" - source: payload name: ref response-message: | Updated, Done. trigger-rule-mismatch-http-response-code: 400 trigger-rule: and: - match: type: payload-hash-sha1 secret: "GitHubに設定するシークレット" parameter: source: header name: "X-Hub-Signature" - match: type: value value: push parameter: source: header name: "X-GitHub-Event" }}} === 後始末 === {{{#!highlight shell numbers=disable sudo restorecon -RFv /etc/systemd/system/snap.webhook.webhook.service.d/ /etc/sysconfig/webhook /etc/httpd/conf/webhook.yaml }}} == InCron == {{{#!highlight shell numbers=disable sudo yum -y install epel-release sudo yum -y install incron sudo systemctl enable incrond sudo systemctl start incrond }}} === /etc/incron.d/update-contents === {{{#!highlight text numbers=disable /root/.webhook/run/activate_id_update-contents IN_CLOSE_WRITE,loopable=false /etc/httpd/libexec/update-contents.sh $$(cat $@) }}} 上記ファイル設定後、以下のコマンドを実行する。 {{{#!highlight shell numbers=disable restorecon -Fv /etc/incron.d/update-contents }}} |
|
行 104: | 行 235: |
}}} | sudo ssh-keygen -t ssh-ed25519 -C root@$(hostname) -N "" -f /root/.ssh/id_ed25519 }}} 以下の点に注意すること。 * `root` 鍵が必要とするため注意。 * パスフレーズの設定は行わない。 = よくある質問とその答え = == Q.ProxyPass設定したならProxyReverseの設定は必須では? == A.よくセットで設定されるので必須扱いなのはわかります。が、webhookには高度な応答(リダイレクトやらクッキーやら)機能が無いので必要ないです。 == Q.ウェブフックへのIPアクセス制限を課したいのだが? == A.`https://api.github.com/meta` の応答(JSON)見ると接続元IPアドレスがリストアップしてますねー(棒)。 詳細は[[https://developer.github.com/v3/meta/|REST API v3 - Meta]] を参考に設定してみてください。時々変更してるようなので頑張ってメンテナンスしてください。 == Q.trigger-ruleはどの程度書けば良くて? == A.例えば、マスターブランチへプッシュ以外は無視という設定は可能です。その場合、マスター以外のブランチへのプッシュはエラー応答するため、!GitHub的にはどうかと(障害と区別がつかない)。 !GitHubのWebhooks設定では、「PUSHイベントのみ」、「全てのイベント」、「個別に指定したイベント」と設定できるので、それを受けられるだけの設定を行うようにしましょう。 == Q.ライトなWebサイト運用してる割には凝った設定では? == A.二度と編集しないようなページを作ってるなら必要ない作業ですね。年に一回くらいしか更新しならペイしないかも。 やれ誤字だ脱字だ、一行追加したい、すぐにやれとかワガママに対応したいならここまでこだわらなくていいでしょう。自分にはとてもても。 == Q.CMS使いたくない割には、GitHub使うって無いのでは? == A.Webコンソールでの作業は抵抗無いのですが、HTMLを直接書きたい向けですね。 要はWikiのような軽量マークアップ言語は使いたくない(制御できない、表現力が低い)、覚えたくない(アレするのにコレ、が思い出せない)人向けというのが。 システムサイドとしては、オマケでイシュー管理(めんどくさい修正の丸投げ)やバージョン管理(勝手に変更の追跡)してくれるお手軽さが重要。 知名度も高いので提案しやすいというのもメリット。 == Q.他のサイトでのやり方見るに、胡乱な手順に見えるけどどうして? == A.おっしゃる通り、あまりに胡乱なので今回、フロー図作りました。あまり合理的で無いことは認めます。 ひとえにスナップクラフトによるコンテナ効果(?)が大きく、webhookが動く環境の外に対してアクション起こせないことが原因です。 唯一ホームディレクトリ(@root@で動いてるので @/root@ ディレクトリ)のみ、下界(コンテナの外)につながってるので、 そこを通してアクション起こしています。 またアクションを即応させるために、incronを使用して最小限の遅延でコンテンツの同期を行えるようにしています。 普通にcron回してると「更新まだ~?」というF5攻撃が…。 == Q.なんでスナップクラフト使ったの? == A.その辺のメジャーなYUMリポジトリで取り扱ってなかったから。またwehookの開発者公認のリポジトリがスナップクラフトだったので使用。ソースからコンパイル?もっと楽に生きようぜ。 |
行 107: | 行 283: |
* [[https://github.com/adnanh/webhook|webhook is a lightweight incoming webhook server to run shell commands.]] * [[https://help.github.com/ja/articles/about-webhooks|webhookについて]] * [[https://developer.github.com/webhooks/|webhooks - GitHub Developer Guide]] * [[https://help.github.com/ja/articles/events-that-trigger-workflows|ワークフローをトリガーするイベント]] * [[https://qiita.com/hana_shin/items/b1a269dbee6d96cb3ace|ユニット定義ファイルの使い方]] |
* webhook関連 * [[https://github.com/adnanh/webhook|webhook is a lightweight incoming webhook server to run shell commands.]] * [[https://snapcraft.io/webhook|Install webhook for Linux using the Snap Store]] * [[https://snapcraft.io/install/webhook/centos|How to install webhook on CentOS]] * [[https://blog.pyyoshi.com/2017/10/26/githubnadonowebhookwozi-qing-nifei-basubian-li-nasaba/|githubなどのwebhookをうけとる便利なGo製サーバー adnanh/webhook]] * [[https://willbrowning.me/setting-up-automatic-deployment-and-builds-using-webhooks/|Setting up Automatic Deployment and Builds Using Webhooks]] * !GitHub関連 * [[https://help.github.com/ja/articles/about-webhooks|webhookについて]] * [[https://developer.github.com/webhooks/|webhooks - GitHub Developer Guide]] * [[https://help.github.com/ja/articles/events-that-trigger-workflows|ワークフローをトリガーするイベント]] * スナップクラフト関連 * [[https://snapcraft.io/docs|Snap documentation]] * systemd関連 * [[https://qiita.com/hana_shin/items/b1a269dbee6d96cb3ace|ユニット定義ファイルの使い方]] * [[https://qiita.com/nvsofts/items/529e422bb8a326401c39|systemdで既存のunitを編集する2つの方法]] * [[https://qiita.com/ch7821/items/369090459769c603bb6b|systemd サービスユニット覚書]] * incron関連 * [[https://qiita.com/k-suzuki/items/4a94ebeda9ec75fdad40|incronを使ってみた]] * [[https://lab.tricorn.co.jp/kicco/483|ファイルやディレクトリのイベントに応じてジョブを実行する]] |
GitHubで回すWebサイト制作
- 思えば、Webサイト制作の現場は、下記のような移り変わりであった気がする。
- エンジニアが作業した(場合によってはHTMLも書く)。
- デザイナーさんが作業するようになった(ちょっとはサーバー側の事情も考慮してくれる)。
- 既存のデザインに対して営業さんがちょこっと修正するようになった(今回の動機)。
- エンジニア・デザイナーさんであれば、FTP(今時はSFTP/SCP)使ってサーバーにアップロードしてくれた。あるいは強制できた。
- 流石に営業さんにそういうツールを使ってもらうのは通じず。
そのために、CSM(Content Management System)導入することもしばしば。
- しかし世の中にはもっとカジュアル(HTML一枚程度)にWebサイト運用したいこともしばしば。
今回、そんなライトな要求に対してGitHubで回す&自動デプロイを実施するための仕組みを作ってみた。
検証環境
- 下記ソフトウェアの利用を前提に検証を実施した。いずれも現時点で最新のリリースに基づいて検証しているが、ある程度古い環境、より新しい環境でも問題無いと思われる。
- ただし、OSについては古いOS(CentOS6等)ではこの手順では実施できない点に注意。
- 上記以外の環境では、以下の点に相違が発生する。当該環境に応じて読み替えたし。
- インストール方法
- インストールされるディレクトリ
- 逆に以下の点は参考にできる。
- 設定パラメータとその意味
- 運用事例
ただし、スナップクラフト固有の問題を回避するためのワークアラウンドだけは別で。
用途 |
ソフトウェア名 |
バージョン番号 |
備考 |
OS |
CentOS 7 |
7.7.1908 |
SELinuxは有効とする |
Webサーバー |
Apache 2.4 |
2.4.41 |
|
Webフック |
2.6.10 |
||
ファイルフック |
incron |
0.5.12 |
ワークアラウンドのために泣く泣く使用 |
検証目標
GitHubに対して以下の設定を行う。
- WebフックのURLの指定
- 秘密鍵の指定
- デプロイ用のSSH鍵の設置
- 上記設定のためにサーバー側のセットアップを行う。
- もちろんWebフックを受けて実際にデプロイを実施する。
- なおApacheの細かい設定については説明しない。
- 今回のシステムは下記のようなフローとなる。
自作スクリプトの設置
ディレクトリ作成
sudo mkdir -p /root/.webhook/bin
sudo mkdir -p /root/.webhook/run
sudo mkdir -p /etc/httpd/libexec
sudo restorecon -RFv /root/.webhook
sudo restorecon -RFv /etc/httpd/libexec
/root/.webhook/run/activate_id_update-contents
以下のコマンドを実行してファイルを作成する。
sudo touch /root/.webhook/run/activate_id_update-contents
sudo restorecon -Fv /root/.webhook/run/activate_id_update-contents
/root/.webhook/bin/fecho
#!/bin/sh
: APPEND=no
: OUTFILE=-
while getopts ao: OPT; do
case $OPT in
a) APPEND=yes
;;
o) OUTFILE=$OPTARG
;;
\?) continue
;;
esac
done
shift $((OPTIND - 1))
if [ x"$OUTFILE" = x"" -o x"$OUTFILE" = x"-" ]; then
echo $*
else
if [ x"$APPEND" = x"yes" ]; then
echo $* >> "$OUTFILE"
else
echo $* > "$OUTFILE"
fi
fi
上記ファイル作成後、下記コマンドを実行すること。
sudo chmod 0755 /root/.webhook/bin/fecho
sudo restorecon -Fv /root/.webhook/bin/fecho
/etc/httpd/libexec/update-contents.sh
#!/bin/sh
cd /var/www/html
git pull -q
if [ x"$1" = x"refs/heads/master" ]; then
git checkout -qf master
restorecon -RF .
fi
ミドルウェアの初期セットアップ
OS
基本的な(とは何かは議論しない)セットアップは実施済みであることとする。
ファイアウォール設定
sudo firewall-cmd --add-service=http --permanent
sudo firewall-cmd --add-service=https --permanent
sudo firewall-cmd --reload
Apache
sudo yum -y install https://centos7.iuscommunity.org/ius-release.rpm
sudo yum -y install httpd24u httpd24u-tools
/etc/httpd/conf/httpd.conf
ProxyPass /hooks/ http://localhost:9000/hooks/
<Proxy *>
Require all granted
</Proxy>
もちろん、本設定は <Virtual ~> ~ </Virtual> 中で設定してもよい。
スナップクラフト
sudo yum -y install snapd
sudo systemctl enable --now snapd.socket
sudo ln -s /var/lib/snapd/snap /snap
sudo systemctl reboot
※スナップクラフトの有効化のために一度再起動しておくこと。
Webhook
sudo snap install webhook
※スナップクラフトが稼働してる状態で上記コマンドを実行すること。
/etc/systemd/system/snap.webhook.webhook.service.d/override.conf
sudo systemctl edit snap.webhook.webhook.service コマンドを呼び出して以下の設定を行う。
[Service] EnvironmentFile=-/etc/sysconfig/webhook ExecStart= ExecStart=/usr/bin/snap run webhook $OPTIONS
※Webhook起動のための設定オプションの指定ができなかったので、/etc/sysconfig/webhook を参照するように改変してみた。
/etc/sysconfig/webhook
OPTIONS="-hooks /etc/httpd/conf/hooks.yaml -hotreload -ip 127.0.0.1 -port 9000"
/etc/httpd/conf/hooks.yaml
- id: update-contents
command-working-directory: "/root"
execute-command: "/root/.webhook/bin/fecho"
pass-arguments-to-command:
- source: string
name: "-o"
- source: string
name: "/root/.webhook/run/activate_id_update-contents"
- source: payload
name: ref
response-message: |
Updated, Done.
trigger-rule-mismatch-http-response-code: 400
trigger-rule:
and:
- match:
type: payload-hash-sha1
secret: "GitHubに設定するシークレット"
parameter:
source: header
name: "X-Hub-Signature"
- match:
type: value
value: push
parameter:
source: header
name: "X-GitHub-Event"
後始末
sudo restorecon -RFv /etc/systemd/system/snap.webhook.webhook.service.d/ /etc/sysconfig/webhook /etc/httpd/conf/webhook.yaml
InCron
sudo yum -y install epel-release
sudo yum -y install incron
sudo systemctl enable incrond
sudo systemctl start incrond
/etc/incron.d/update-contents
/root/.webhook/run/activate_id_update-contents IN_CLOSE_WRITE,loopable=false /etc/httpd/libexec/update-contents.sh $$(cat $@)
上記ファイル設定後、以下のコマンドを実行する。
restorecon -Fv /etc/incron.d/update-contents
デプロイ用SSH鍵の準備
sudo ssh-keygen -t ssh-ed25519 -C root@$(hostname) -N "" -f /root/.ssh/id_ed25519
以下の点に注意すること。
root 鍵が必要とするため注意。
- パスフレーズの設定は行わない。
よくある質問とその答え
Q.ProxyPass設定したならProxyReverseの設定は必須では?
A.よくセットで設定されるので必須扱いなのはわかります。が、webhookには高度な応答(リダイレクトやらクッキーやら)機能が無いので必要ないです。
Q.ウェブフックへのIPアクセス制限を課したいのだが?
A.https://api.github.com/meta の応答(JSON)見ると接続元IPアドレスがリストアップしてますねー(棒)。
詳細はREST API v3 - Meta を参考に設定してみてください。時々変更してるようなので頑張ってメンテナンスしてください。
Q.trigger-ruleはどの程度書けば良くて?
A.例えば、マスターブランチへプッシュ以外は無視という設定は可能です。その場合、マスター以外のブランチへのプッシュはエラー応答するため、GitHub的にはどうかと(障害と区別がつかない)。 GitHubのWebhooks設定では、「PUSHイベントのみ」、「全てのイベント」、「個別に指定したイベント」と設定できるので、それを受けられるだけの設定を行うようにしましょう。
Q.ライトなWebサイト運用してる割には凝った設定では?
A.二度と編集しないようなページを作ってるなら必要ない作業ですね。年に一回くらいしか更新しならペイしないかも。
やれ誤字だ脱字だ、一行追加したい、すぐにやれとかワガママに対応したいならここまでこだわらなくていいでしょう。自分にはとてもても。
Q.CMS使いたくない割には、GitHub使うって無いのでは?
A.Webコンソールでの作業は抵抗無いのですが、HTMLを直接書きたい向けですね。
要はWikiのような軽量マークアップ言語は使いたくない(制御できない、表現力が低い)、覚えたくない(アレするのにコレ、が思い出せない)人向けというのが。 システムサイドとしては、オマケでイシュー管理(めんどくさい修正の丸投げ)やバージョン管理(勝手に変更の追跡)してくれるお手軽さが重要。 知名度も高いので提案しやすいというのもメリット。
Q.他のサイトでのやり方見るに、胡乱な手順に見えるけどどうして?
A.おっしゃる通り、あまりに胡乱なので今回、フロー図作りました。あまり合理的で無いことは認めます。
ひとえにスナップクラフトによるコンテナ効果(?)が大きく、webhookが動く環境の外に対してアクション起こせないことが原因です。 唯一ホームディレクトリ(@root@で動いてるので @/root@ ディレクトリ)のみ、下界(コンテナの外)につながってるので、 そこを通してアクション起こしています。
またアクションを即応させるために、incronを使用して最小限の遅延でコンテンツの同期を行えるようにしています。 普通にcron回してると「更新まだ~?」というF5攻撃が…。
Q.なんでスナップクラフト使ったの?
A.その辺のメジャーなYUMリポジトリで取り扱ってなかったから。またwehookの開発者公認のリポジトリがスナップクラフトだったので使用。ソースからコンパイル?もっと楽に生きようぜ。
参考文献
- webhook関連
GitHub関連
- スナップクラフト関連
- systemd関連
- incron関連