😇

M1macでのDockerfileのBuildで鬼沼った話

2022/08/05に公開

今回は、DockerfileをBuildしECRにプッシュ。その後ECSでタスク実行という一般的な流れで沼った話です。

standard_init_linux.go:228: exec user process caused: exec format errorになる

M1macでビルドしたimageをECRにプッシュし、ECSでタスク実行すると上記のようなエラーが出ました。

docker inspect [imagename]:latest

で、作成したimageの中身を確認すると、たしかに"Architecture"が"arm64"になってるんですよね。

この辺は、DevelopersIOの「Dockerのマルチアーキテクチャイメージについて調べてみた」という記事があるので、そちらを読んでいただければ理解できると思います。

要するに、ビルドしたのはarm64のパソコンでイメージもarm64用なのに、実行しているのはx86_64なのでアーキテクチャが違いますよーとエラーが出てるわけですね。

解決策は大きく分けて2つです。

  • 同じアーキテクチャのパソコン(サーバー)でビルドする
  • 実行する環境を合わせる

同じアーキテクチャのパソコン(サーバー)でビルドする

おなじアーキテクチャのPCでビルドすれば問題なく実行できます。

例えばlinux/x86_64環境のEC2上に、Dokerfileなどの必要なファイルをアップし、そこでビルド。
ECRにプッシュするという方法です。この方法であればアーキテクチャの差異は生まれません。

また、buildxでマルチアーキテクチャに対応した形にビルドする方法もあります。その際は、ローカルに保存してもarm64に対応したイメージしか残らないので、doker hubにプッシュするようにしてビルドしましょう。
https://docs.docker.jp/docker-for-mac/multi-arch.html

Doker hub上のイメージをlinux/x86_64環境のEC2でpullした上で、ECRにプッシュすることでエラーなく実行できるようになります。

他には、使用するファイルをGithubにアップロードし、AWSのcodebuildを使ってビルドする方法もあります。
https://dev.classmethod.jp/articles/20170225-codebuild-docker/
最適なのは最後に紹介した、codebuildでビルドする方法でしょう。

実行する環境を合わせる

私は今回はこの方法で解決しました。
最も簡単だったからです。

最初は気づかなかったのですが、ECSのコンソール画面の左上には「新しい ECS エクスペリエンス」なる箇所があります。こちらをクリックすると、コンソール画面が変わり、タスク定義を作成する際にarm64が選べるようになるのです。

こちらでアーキテクチャをARM64にすることで該当するエラーは解決できます。

Discussion