DockerfileでCPUアーキテクチャごとにFROMを切り替える

注意事項

この記事は、Notion AIに対して

  • 問題と解決策の概要
  • 例示用のコード

を渡して生成した実験的な記事になります。

はじめに

この記事では、複数のCPUアーキテクチャが存在する場合に、DockerのFROMを切り替える方法について説明します。
例えば、Apple Siliconに対応する場合に便利です。

本記事の対象外

本記事では各プラットフォームごとのイメージが、同一タグで提供されている場合や、タグにアーキテクチャの識別子が入っているようなケースを扱わないことに注意してください。

例えば以下のようなケースです。

# 同一タグで複数プラットフォームが提供されている
FROM alpine:3
# 異なるタグだが、タグにアーキテクチャの識別子が入っている
# - example:amd64
# - example:arm64
FROM example:${TARGETARCH}

これらは言うまでもなく、よくあるパターンです。
今回紹介する方法もよくあるパターンといえばそうかもしれませんが、中々見つからなかったので共有になります。

モチベーション

GitHub Actionsの1ステップのdocker/build-push-actionで、複数プラットフォームのイメージをビルドする場合、CPUアーキテクチャごとにイメージを別途用意する必要があります。
アーキテクチャごとにイメージを用意する場合、同一タグで複数プラットフォームのイメージを配布するにはdocker manifestなど多少手間がかかります。 ※1
そのため、1ステップにまとめることさえできるとWorkflow自体はとてもシンプルなものを維持することができます。

この記事を書きながら思っていますが、こんな変なことをしなくても楽にできる方法は既に生まれているかもしれません。

CPUアーキテクチャごとにFROMを切り替える方法

本記事では、amd64ならubuntu:22.04、arm64ならalpine:3のイメージを使用することを例に説明します。

察しの言い方であれば既にイメージできると思いますが、amd64やarm64などのステージを用意することで、CPUアーキテクチャごとにイメージを別のものに切り替えることができます。

FROM ubuntu:22.04 as amd64
RUN ...

FROM alpine:3 as arm64
RUN ...

FROM ${TARGETARCH} as app

FROM自体に指定できる変数は、ARGやTARGETARCHなど事前に提供されたもののみですが、amd64やarm64などのステージを用意することで、FROMの切り替えが可能になります。

当たり前といえば当たり前なんですが、小一時間ほど悩んでいたのでので他にもやりたい人がいれば是非参考にしてみてください。

おわりに

今回は、CPUアーキテクチャごとにDockerのFROMを切り替える方法について説明しました。
複数のCPUアーキテクチャが存在する場合には、この方法を使用することで効率的に開発することができます。