GitHub Action で Docker マルチアーキテクチャ(x86_64 / arm64)ビルド

GitHub Action で Docker をマルチアーキテクチャ(x86_64 and arm64)でビルドし、それを Docker Hub へ公開するまでの一連のビルド設定

実現したいこと

  • GitHub Action で Docker をマルチアーキテクチャ(x86_64 and arm64)でビルドする
  • Docker Hub へ公開する
name: Publish Docker image

on:
  push:
    tags:
      - "v*"
  workflow_dispatch:

jobs:
  push_to_registry:
    name: Push Docker image to Docker Hub
    runs-on: ubuntu-22.04

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

      - name: Docker meta
        id: metadata
        uses: docker/metadata-action@v4
        with:
          images: username/repository-name
          tags: |
            type=semver,pattern={{version}}
            type=semver,pattern={{major}}.{{minor}}            

      - name: Login to Docker Hub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - # Add support for more platforms with QEMU (optional)
        # https://github.com/docker/setup-qemu-action
        name: Set up QEMU
        uses: docker/setup-qemu-action@v2

      - name: Set up Docker Buildx
        id: buildx
        uses: docker/setup-buildx-action@v2
        with:
          platforms: linux/amd64,linux/arm64

      - name: Build and Push to Docker Hub
        uses: docker/build-push-action@v2
        with:
          context: .
          builder: ${{ steps.buildx.outputs.name }}
          platforms: ${{ steps.buildx.outputs.platforms }}
          push: true
          tags: ${{ steps.metadata.outputs.tags }}
          labels: ${{ steps.metadata.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

初学にあたって全体感を掴むと作業が捗りやすい。

  • tag が push された時にのみ自動実行する
  • workflow_dispatch により、GitHub の GUI上から Actions タブで手動実行することができる
  • Ubuntu 22.04 で実行する(latest とも書ける)
  • actions/checkout はコードのチェックアウト
  • docker/metadata-action はレポジトリの情報を材料にして tag 名などを決定できる。ここで決めたルールに基づいてこのあとの tag が作られる。
  • docker/login-action は Docker レジストリへログインする。その他複数の Registry へログインする場合は同様に並べて記載できる。
  • docker/setup-qemu-action はマルチアーキテクチャ向けビルドをする時に利用する。
    • なお amd64 だけなら2分で終わったビルドが、 arm64 を含めた途端に 15分程かかって非常に遅くなった。
  • docker/setup-buildx-action はビルド用のセットアップ。 with でビルド対象のプラットフォームを指定している。
  • docker/build-push-action は最後の処理で、ビルドとDocker レジストリへの push を担う。
    • cache-to / cache-from では、キャッシュの方法を指定する。 type=gha は 2022/11 月現在 Experimental の状態であるが、使ってみて動くようならお手軽なのでお勧め。他の手段だともう少しコードを書くことにもなる。

それぞれのアクションのバージョンは @数字 と記載されているが、ネット記事の情報よりも最新版が出ていることが多かったため、GitHubで最新版を確認するのが望ましい。

実行例

1回のビルドで以下のことをやってくれる。よく見慣れた画面。

  • 複数のバージョン付(メジャーバージョン、フルバージョン、および latest)
  • arm64 と amd64 向けの2つのビルド

Docker Hub ビルド結果

Docker Login

Docker Hub のほか GCR や ECR などの各種レポジトリへのアクセス方法の記載あり。

Docker Login - GitHub Marketplace

Docker Login - GitHub Marketplace

GitHub Action to login against a Docker registry

Access Tokens

Docker Hub にて Access Token を作成しておく。自身のユーザーID・パスワードは利用しない方がよい。

Docker Hub Access Token

管理しやすい名前をつけて作成。

Repository secrets / Environment secrets

以下の部分で Docker へログインするための秘密情報をベタで記載するわけにはいかないので、GitHub にて保存しておける。それぞれのレポジトリの Setting タブ内のメニューで設定可能。

# 再掲
- name: Login to Docker Hub
  uses: docker/login-action@v2
  with:
    username: ${{ secrets.DOCKERHUB_USERNAME }}
    password: ${{ secrets.DOCKERHUB_TOKEN }}

Organization and repository secrets are read when a workflow run is queued, and environment secrets are read when a job referencing the environment starts.

GitHub Actions でのシークレットの使用 - GitHub Docs

GitHub Actions でのシークレットの使用 - GitHub Docs

Cache

Introduction to GitHub Actions

Introduction to GitHub Actions

Docker maintains a set of official GitHub Actions for building Docker images.

Actions