🤖

docker/build-push-actionでマルチプラットフォームイメージにタグを打つ

2022/04/30に公開

はじめに

私は、GitHubのcontribution数を年または月単位で集計するツールをDockerイメージとして公開しています。

M1 Macを使うようになり(長らく放置していましたが)ARM対応することにしました。

  • linux/amd64
  • linux/arm64

をサポートするマルチプラットフォームイメージの公開を試みました。単純にdocker tagdocker pushをすると、linux/amd64linux/arm64の片方のみにタグが付いてしまいました。

docker/build-push-actionを利用して解決したため、紹介します。

解決した課題

docker pulldocker runを実行する環境にあわせて適切なイメージをダウンロードできるようにしました。Docker Hubでは以下のようにOS/ARCHを選択できます。

multi-platform-image-on-docker-hub

GitHub Actionsにおける解決方法

Docker公式のGitHub Actionsを利用すると簡単です。

  1. docker/setup-qemu-actionを実行する
  2. docker/setup-buildx-actionを実行する
  3. platformtagを指定してdocker/build-push-actionを実行する

mainブランチに対するpushをトリガーとしてdocker push [options] $REPOSITORY:latestするサンプルはこちらです。

https://github.com/oke-py/contributions/blob/855aa37938dd92bb87485bb32c6b0b7de2546f7d/.github/workflows/docker.yml

GitHubリポジトリでタグを作成したときにdocker push [options] $REPOSITORY:$TAGすることもできます。

https://github.com/oke-py/contributions/blob/855aa37938dd92bb87485bb32c6b0b7de2546f7d/.github/workflows/docker-tag.yml

実行コマンドの再現

やりたいことはできましたが、もう少し追いかけてみます。どのようなdockerコマンドを実行しているのか、ソースコードを読んで解き明かします。

main.tsを読むと、dockerコマンドの引数にargs変数を指定しているとわかります。
https://github.com/docker/build-push-action/blob/ba317382dcde9f7deb318467fc6cd7230d8b1714/src/main.ts#L25-L34

このargscontext.tsgetArgs関数の返り値です。
https://github.com/docker/build-push-action/blob/ba317382dcde9f7deb318467fc6cd7230d8b1714/src/context.ts#L101-L109

getBuildArgs関数とgetBuildArgs関数は、設定値をもとにひたすらオプションを追加しています。長いので抜粋します。

https://github.com/docker/build-push-action/blob/ba317382dcde9f7deb318467fc6cd7230d8b1714/src/context.ts#L111-L115

前述のサンプルをもとにした、コマンドの再現結果はこちらです。可読性のため適宜改行します。

docker buildx build \
  --platform linux/amd64,linux/arm64 \
  --tag okepy/contribution:latest \
  --push \
  .

へー、こうするのですね。知りませんでした。

再現したコマンドをM1 Macで実行

[+] Building 0.0s (0/0)                                                                                                                                       
error: multiple platforms feature is currently not supported for docker driver. Please switch to a different driver (eg. "docker buildx create --use")

むむ、エラーとなりました。以下のIssueを読むと、解決方法に挙げた

  • docker/setup-qemu-action
  • docker/setup-buildx-action

が必要となることがわかります(私はここで満足してしまったため、試していません)。

https://github.com/docker/build-push-action/issues/302

おわりに

Docker公式のGitHub Actionsを活用することで、簡単にマルチプラットフォームイメージを作成できました。

マルチプラットフォームイメージと言えば、Cybozu Productivity News #2 - 2022.04.28でビルド高速化の方法が紹介されました。docker manifest 知りませんでした。なお、こちらの記事ではマルチアーキテクチャ対応イメージと表現されています。

https://poyo.hatenablog.jp/entry/2021/09/25/225329

参考

https://github.com/docker/build-push-action

GitHubで編集を提案

Discussion