基幹システムグループ N1! オートメーションスペシャリストの南川です。
今回は、 Docker イメージがビルドできるか定期的にチェックし、失敗したら Slack に通知する GitHub Actions のワークフローを紹介します。
背景
Docker のベースイメージの OS や使用しているパッケージのバージョンアップにより、何もしていないのに Docker イメージのビルドが失敗するようになることがあるかと思います。また、ビルドに失敗した場合、その原因が機能追加や修正によるものなのか、自分の環境によるものなのか分からないといった問題もあります。
こうした背景から、以下のような GitHub Actions のワークフローを作成することにしました。
- 定期的 (平日 8:30) に Docker イメージのビルドが成功するかチェックする。
- ビルドに失敗したら Slack のチャンネルにアラートを通知する。
もし、 Slack チャンネルにアラートが通知されていたら、担当者はワークフローの実行ログを確認し、 GitHub で Issue を作成して対応します。
このワークフローにより、ベースイメージやパッケージの更新による Docker イメージのビルド失敗の検知が迅速化されるほか、ビルド失敗の原因の調査にも役立つことが期待されます。
手順
前提として、今回は Docker Compose を使っているリポジトリに対して実装していきます。
(1) Slack Incoming Webhook を作成
- 以下のページを参考に Slack Incoming Webhook を作成します。
- 作成したら Webhook URL (
https://hooks.slack.com/services/T.../B.../...
) をメモします。
(2) Webhook URL をリポジトリシークレットに追加
- GitHub のリポジトリのページを開きます。
- リポジトリのメニューから「 Settings 」を選択します。
- 左メニューから「 Secrets and variables > Actions 」を選択します。
- 「 New repository secret 」ボタンを押す。
- 以下のように入力し、「 Add secret 」ボタンを押す。
- Name :
ALERT_SLACK_WEBHOOK_URL
- Secret : 手順 (1) でメモした Webhook URL
- Name :
(3) GitHub Actions ワークフローファイルを作成
- ブランチを切り、
.github/workflows/
配下に以下のファイル (check_docker_build.yml
) を作成します。
[修正 2024/04/03]
ubuntu イメージから Docker Compose V1 が削除されたのに伴い、 docker-compose build
コマンドを docker compose build
コマンドに差し替えました。
詳しくは以下の記事をご確認ください。
https://engineering.nifty.co.jp/blog/26217
参考 : https://github.com/actions/runner-images/issues/9557
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
name: check docker build on: schedule: - cron: '30 23 * * 0,1,2,3,4' workflow_dispatch: jobs: check_build: runs-on: ubuntu-latest steps: - name: checkout uses: actions/checkout@v3 - name: define run url run: echo "ACTION_URL=https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" >> $GITHUB_ENV - name: docker compose build run: docker compose build - name: slack notification if: ${{ failure() }} uses: slackapi/slack-github-action@v1.24.0 with: payload: | { "text": ":github: Dockerイメージのビルド失敗 :docker:\n失敗の原因を調査し、必要に応じてhotfixのIssueを作成し、対応してください。", "blocks": [ { "type": "section", "text": { "type": "mrkdwn", "text": ":github: Dockerイメージのビルド失敗 :docker:" } }, { "type": "section", "text": { "type": "mrkdwn", "text": "失敗の原因を調査し、必要に応じてhotfixのIssueを作成し、対応してください。" } }, { "type": "section", "text": { "type": "mrkdwn", "text": "${{ env.ACTION_URL }}" } } ] } env: SLACK_WEBHOOK_URL: ${{ secrets.ALERT_SLACK_WEBHOOK_URL }} SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK |
- この時のディレクトリ構成 (関係のあるファイルのみ) は以下のようになります。
1 2 3 4 5 |
|-- .github | `-- workflows | `-- check_docker_build.yml |-- Dockerfile `-- docker-compose.yml |
解説
1 |
name: check docker build |
- リポジトリの Actions タブで表示されるワークフロー名を指定しています。
- https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#name
- ここで指定した名前は、 Actions タブの実行履歴で表示されます。
1 2 3 4 |
on: schedule: - cron: '30 23 * * 0,1,2,3,4' workflow_dispatch: |
- このワークフローを実行するトリガー (条件) をここで指定しています。
schedule
https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#schedule
- cron 式で指定した日時に実行するようにする。
- UTC で指定する必要があるので注意。
- (例) 月曜日 (曜日 = 1) 8:30 を指定する場合は、 UTC に変換すると、日曜日 (曜日 = 0) 23:30 になるので、「
30 23 * * 0
」となります。
- (例) 月曜日 (曜日 = 1) 8:30 を指定する場合は、 UTC に変換すると、日曜日 (曜日 = 0) 23:30 になるので、「
- 今回は平日 (月曜~金曜) の 8:30 に実行するようにしています。
workflow_dispatch
https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_dispatch
- ワークフローを手動で実行できるようにします。
- 今回はワークフローの動作確認のために使います。
1 2 |
- name: checkout uses: actions/checkout@v3 |
- リポジトリにチェックアウトし、ワークフローでアクセスできるようにします。
1 2 |
- name: define run url run: echo "ACTION_URL=https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" >> $GITHUB_ENV |
- 環境変数
ACTION_URL
を定義し、環境ファイル$GITHUB_ENV
に書き込みます。- ワークフローの実行結果のURLを環境変数
ACTION_URL
の値として定義しています。
- ワークフローの実行結果のURLを環境変数
${GITHUB_REPOSITORY}
,${GITHUB_RUN_ID}
はそれぞれ GitHub が設定済みの既定の環境変数。${GITHUB_REPOSITORY}
: 所有者およびリポジトリ名。${GITHUB_RUN_ID}
: リポジトリ内の各ワークフローの実行に割り振られたユニークな番号。- https://docs.github.com/ja/actions/learn-github-actions/variables#default-environment-variables
$GITHUB_ENV
はワークフローコマンドから変数を設定するファイルへのランナー上のパス。- これによって、後続のステップで環境変数
ACTION_URL
の値を使うことができます。
1 2 |
- name: docker-compose build run: docker-compose build |
- Docker イメージをビルドするコマンド。
- 必要に応じて 「–build-arg」 でオプションを指定します。
1 2 |
- name: slack notification if: ${{ failure() }} |
- 前のステップ (Docker イメージのビルド)が失敗した場合に、このステップを実行(Slackにメッセージを投稿)するようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
uses: slackapi/slack-github-action@v1.24.0 with: payload: | { "text": ":github: Dockerイメージのビルド失敗 :docker:\\n失敗の原因を調査し、必要に応じてhotfixのIssueを作成し、対応してください。", "blocks": [ ... { "type": "section", "text": { "type": "mrkdwn", "text": "${{ env.ACTION_URL }}" } } ] } env: SLACK_WEBHOOK_URL: ${{ secrets.ALERT_SLACK_WEBHOOK_URL }} SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK |
- Slack Incoming Webhook を用いて、メッセージを Slack チャンネルに投稿します。
- payload には Slack チャンネルに投稿するメッセージを記載します。
text
https://api.slack.com/methods/chat.postMessage#arg_text
- blocks が指定されていない場合、チャンネルに投稿されるメッセージ。
- blocks が指定されている場合、 Slack で通知されるときのメッセージ。
block
https://api.slack.com/methods/chat.postMessage#arg_blocks
- JSON で記述された構造化されたメッセージ。
- 詳しくはこちらを参照してください。
- 先ほど定義した環境変数
ACTION_URL
の値を使っています。
「"text": "${{ env.ACTION_URL }}"
」 - 環境変数
SLACK_WEBHOOK_URL
に、手順(2)で設定したリポジトリシークレットの値を指定しています。
(4) 動作確認
- ビルドを失敗するように Dockerfile を書き換えてコミットし、 push します。
- リポジトリの「Settings」タブを選択します。
- Default branch をこのワークフローを開発しているブランチに切り替えます。
- リポジトリの 「Actions」 タブを選択します。
- 左メニューから 「check docker build」 を選択します。
- 「Run workflow」 のプルダウンを開き、現在開発しているブランチを指定して、緑色の 「Run workflow」 ボタンを押します
- しばらくすると、チャンネルにビルド失敗のメッセージが投稿されます。
- Botのアイコンがお気に入りです。
- 平日の8:30頃にビルド失敗通知に投稿されれば OK。
- ビルド失敗するようにしたコミットを revert します。
- 平日の8:30頃にビルド失敗通知に投稿されなければ OK。
- Actionsタブから実行されている(Dockerイメージのビルド成功している)ことを確認します。
- 土日の8:30頃にワークフローが実行されていなければOK。
- Actionsタブから実行されていないことを確認します。
おわりに
今回は、GitHub Actions で定期的に Docker イメージをビルドできるかチェックし、ビルドできない場合は Slack にメッセージを投稿するワークフローについて説明しました。 Docker イメージのビルドチェック以外にも色々応用できるので、是非活用してみてください。
We are hiring!
ニフティでは、さまざまなプロダクトへ挑戦するエンジニアを絶賛募集中です!
ご興味のある方は以下の採用サイトよりお気軽にご連絡ください!
カジュアル面談も受け付けています!
Tech TalkやMeetUpも開催しております!
こちらもお気軽にご応募ください!