🐳

ARMとAMDの2つのコンピューターで1つDockerイメージを作る

2022/08/03に公開

はじめに

AppleのM1コアの登場などにより、DockerイメージもARM64プラットフォームへの対応が求められているが、docker buildx build --platform linux/amd64,linux/arm64をそのまま用いるやり方は、たとえばこのコマンドを動作させているコンピューターがIntel(AMD64)プラットフォームである場合、ARM64側はQEMUによるエミュレーション下でDockerのビルドとなるため非常に低速となり時間がかかる。もし手元にIntelなどのAMD64のコンピューターとM1 MacなどのARM64のコンピューターがあれば、この2つでそれぞれAMD64とARM64のイメージを作成して1つにまとめたいと考えた人がいると思う。
この記事では下記の@falmsさんの情報を元に、このような2台の別プラットフォームのコンピューターを利用して2プラットフォーム対応なDockerイメージを作成する手順を解説する。

ほとんどこのツイートに書かれていることが全てではあるが、もし何かコメントなどがあれば気軽に教えてほしい。

手順

この記事ではlinux/amd64linux/arm64の2つのプラットフォームに対応するイメージを2台のコンピューターで作成するという例で説明する。なお、用いる2台のコンピューターは筆者の手元にある次の2台を想定する。

  • Intel Mac …… linux/amd64なDockerイメージを作るのが得意なコンピューター
  • M1 Mac …… linux/arm64なDockerイメージを作るのが得意なコンピューター

また作成するDockerイメージは、筆者が所属するCTFチームがコミックマーケット100向けに作成している同人誌をコンパイルするためのDockerイメージであるur4nd0m/c100とする。

  1. 2台のコンピューターでそれぞれ次のようなコマンド[1]を実行してDockerイメージを作成しDocker Hubなどにプッシュする。このときイメージのタグをそれぞれlatest-amd64/latest-arm64としておき、別々にする
    • Intel Mac
      $ docker buildx build --platform linux/amd64 --push -t ur4nd0m/c100:latest-amd64 .
      
    • M1 Mac
      $ docker buildx build --platform linux/arm64 --push -t ur4nd0m/c100:latest-arm64 .
      
  2. Intel MacまたはM1 Macのどちらかで、反対側でビルドしたイメージをdocker pullする
    • ここではIntel Macで行うものとして次のようになる
      $ docker pull ur4nd0m/c100:latest-arm64
      
    • 成功すると手順(1)で作成した2つのイメージがIntel Mac側に両方とも存在する
      $ docker images | grep ur4nd0m/c100 | grep  latest-
      ur4nd0m/c100                                    latest-amd64      1e78fe1e54eb   8 minutes ago    1.38GB
      ur4nd0m/c100                                    latest-arm64      6f2195862e18   21 minutes ago   1.45GB
      
  3. 手順(2)を行ったコンピューター(例ではIntel Mac)で次のコマンドを実行し1つにする
    $ docker manifest create ur4nd0m/c100:latest ur4nd0m/c100:latest-amd64 ur4nd0m/c100:latest-arm64
    Created manifest list docker.io/ur4nd0m/c100:latest
    
  4. 手順(3)を行ったコンピューターでイメージをプッシュする
    $ docker manifest push ur4nd0m/c100:latest
    

まとめ

このようにするとかなり高速に各プラットフォームのDockerイメージを作成できて非常に便利だと思う。@falmsさんの有益な情報に感謝したい。

脚注
  1. ここではdocker buildx buildを使っているが、docker buildでもよいと思う。 ↩︎

Discussion