docker/build-push-actionでマルチプラットフォームイメージにタグを打つ
はじめに
私は、GitHubのcontribution数を年または月単位で集計するツールをDockerイメージとして公開しています。
M1 Macを使うようになり(長らく放置していましたが)ARM対応することにしました。
- linux/amd64
- linux/arm64
をサポートするマルチプラットフォームイメージの公開を試みました。単純にdocker tag
とdocker push
をすると、linux/amd64
とlinux/arm64
の片方のみにタグが付いてしまいました。
docker/build-push-action
を利用して解決したため、紹介します。
解決した課題
docker pull
やdocker run
を実行する環境にあわせて適切なイメージをダウンロードできるようにしました。Docker Hubでは以下のようにOS/ARCH
を選択できます。
GitHub Actionsにおける解決方法
Docker公式のGitHub Actionsを利用すると簡単です。
-
docker/setup-qemu-action
を実行する -
docker/setup-buildx-action
を実行する -
platform
とtag
を指定してdocker/build-push-action
を実行する
main
ブランチに対するpushをトリガーとしてdocker push [options] $REPOSITORY:latest
するサンプルはこちらです。
GitHubリポジトリでタグを作成したときにdocker push [options] $REPOSITORY:$TAG
することもできます。
実行コマンドの再現
やりたいことはできましたが、もう少し追いかけてみます。どのようなdocker
コマンドを実行しているのか、ソースコードを読んで解き明かします。
main.ts
を読むと、docker
コマンドの引数にargs
変数を指定しているとわかります。
このargs
はcontext.ts
のgetArgs
関数の返り値です。
getBuildArgs
関数とgetBuildArgs
関数は、設定値をもとにひたすらオプションを追加しています。長いので抜粋します。
前述のサンプルをもとにした、コマンドの再現結果はこちらです。可読性のため適宜改行します。
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
が必要となることがわかります(私はここで満足してしまったため、試していません)。
おわりに
Docker公式のGitHub Actionsを活用することで、簡単にマルチプラットフォームイメージを作成できました。
マルチプラットフォームイメージと言えば、Cybozu Productivity News #2 - 2022.04.28でビルド高速化の方法が紹介されました。docker manifest
知りませんでした。なお、こちらの記事ではマルチアーキテクチャ対応イメージと表現されています。
参考
Discussion