APC 技術ブログ

株式会社エーピーコミュニケーションズの技術ブログです。

株式会社 エーピーコミュニケーションズの技術ブログです。

GitHub Actionsでコンテナイメージ作成時に手軽にタグ付けする

はじめに

みなさん、CIやCDの自動化進んでいますか?

ユニットテストコードをきちんと書いているところはテストの自動化は比較的早期に実現しているのではないでしょうか。

ではデプロイについてはどうでしょうか?例えばコンテナイメージのビルドはどうしていますか?ビルドするだけはなく、タグも適切に付与しないといけないのだけど、タグ名とかどのように自動化していますか?

この点は意外に悩んでいることも多いのではないかと思います。

今回はそんなコンテナイメージのタグ付けの自動化を簡単にする GitHub Actionをご紹介したいと思います。 これ1つ知っているか知らないかの違いで、実現容易性が格段に変わってくると思います。

GtHub Actionでのコンテナイメージのタグ付け

name: build-image
on:
  push:
    tags:
    - 'v*'
  pull_request:
    branches:
    - 'main'
  workflow_dispatch:

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build:
    name: build image
    runs-on: ubuntu-latest

    # Sets the permissions granted to the GITHUB_TOKEN for the actions in this job.
    permissions:
      contents: read
      packages: write

    steps:
    - name: checkout
      uses: actions/checkout@v3

    # see: https://github.com/docker/metadata-action
    - name: Extract metadata (tags, labels) for Docker
      id: meta
      uses: docker/metadata-action@v4
      with:
        images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
        tags: |
          type=ref,event=branch
          type=semver,pattern={{version}}
          type=sha
        labels: |
          org.opencontainers.image.title=sample-app
          org.opencontainers.image.vendor="AP Communications Co.,Ltd."
          org.opencontainers.image.licenses=Apache-2.0

    # see: https://github.com/docker/login-action#github-container-registry
    - name: Log in to the Container registry
      uses: docker/login-action@v2
      with:
        registry: ${{ env.REGISTRY }}
        username: ${{ github.actor }}
        password: ${{ secrets.GITHUB_TOKEN }}

    # see also https://github.com/docker/metadata-action
    - name: Build and push
      id: build-and-push
      uses: docker/build-push-action@v4
      with:
        context: ./
        file: ./Dockerfile
        push: ${{ github.event_name != 'pull_request' }}
        tags: ${{ steps.meta.outputs.tags }}
        labels: ${{ steps.meta.outputs.labels }}

お手軽にやる方法、そのポイントは docker/metadata-action です。

github.com

ここで、コンテナイメージに付与するタグやラベルをいい感じに設定します。 ラベルについては、イメージ作成時に指定した内容で上書きするというものです。(ドキュメントはこちら)well-knownなラベルはこちらをご覧ください。

        labels: |
          org.opencontainers.image.title=sample-app
          org.opencontainers.image.vendor="AP Communications Co.,Ltd."
          org.opencontainers.image.licenses=Apache-2.0

そしてタグ。これは結構悩まれている方もいらっしゃるのではないでしょうか。 docker/metadata-action ではGitHub Action実行時のイベント情報をベースにタグを決定します。(ドキュメントはこちらです)

        tags: |
          type=ref,event=branch
          type=semver,pattern={{version}}
          type=sha

ここでは3つのタグをつけるように指示しています。

type=sha はすぐにイメージできるのではないでしょうか。GitHubのshort commit をタグとして付与します。

type=ref,event=branch は 処理対象のブランチ名を 付与します。mainにマージしたときは main、 test-branch でこのGitHub Actionsを手動で実行した場合には test-branch という名称のタグを付与します。

type=semver,pattern={{verson}} はリポジトリにタグ付けしたときに付与されるもので、 リポジトリ側 v1.0.0というタグをつけたら、1.0.0 というタグをコンテナイメージ側に付与します。 バージョン部分の命名はいくつかオプションがありますので、公式ドキュメントをご確認ください。この例では

on:
  push:
    tags:
    - 'v*'
  pull_request:
    branches:
    - 'main'
  workflow_dispatch:

とトリガーを指定していますので、リポジトリにタグ付けされたらコンテナイメージをビルドし、タグ付けされたバージョン情報がコンテナイメージでも付与されるようになります。 (コンテナイメージが作成されたら、デプロイフローを実行するようGitOpsで指定していれば、GitHubのタグ付けを契機にデプロイまでが自動化できますね)

ラベルやタグを設定したらあとはそれをコンテナイメージのビルド・プッシュ時に指定すればOK。

    - name: Build and push
      id: build-and-push
      uses: docker/build-push-action@v4
      with:
        context: ./
        file: ./Dockerfile
        push: ${{ github.event_name != 'pull_request' }}
        tags: ${{ steps.meta.outputs.tags }}
        labels: ${{ steps.meta.outputs.labels }}

タグやラベルは tags、labelsで指定しています。簡単ですね。

以前は「どのタイミングでコンテナイメージ作成しようか」「タグ付けはどう自動化しようか」など悩んでいたこともありましたが、docker/metadata-action があればその悩みからも解消されるのではないかと思います。

おわりに

弊社では「DevOps導入支援サービス for GitHub Enterprise」を2023年7月21日にリリースいたしました。当社は、マイクロソフトの「Advanced Specialization」を「DevOps with GitHub on Microsoft Azure」分野で取得しているとともに、GitHub とのパートナー契約を締結しております。

GitHubを組織内で活用したい、より効率的に、よりセキュアに、と興味をお持ちでしたらぜひご連絡ください。

www.ap-com.co.jp