【ECS】exec user process caused: exec format errorの原因と対処法
Rails+Docker環境にてECS側(Fargate使用)のコンテナ起動時に下記エラーに悩まされたので、その調査結果と解決策をシェアしたいと思います。
standard_init_linux.go:228: exec user process caused: exec format error
原因
結論から言うとM1 Macで作成したイメージを、コンテナが動作するFargateのCPUアーキテクチャ側が読み込むことができないのが原因のようです。
CPUアーキテクチャとはその名の通りCPU側の設計を指しており、この設計には種類があります。有名どころで言うと、x86(intel)とARM(ARM)が存在します。今回問題だったのは、このCPUアーキテクチャがM1でビルドした際はARMで作成され、FargateのCPUアーキテクチャではARM作成されたイメージは対応できない為でした。
試しにターミナルから下記コマンドで、自分のMac(M1)のCPUアーキテクチャを確認したところ確かにARMであることが確認できました。
# 実行しているOSの名前やバージョンなどを出力
uname -m
対策
対策として、以下の2案のどちらかで解決することができます。個人的に②の方が、都度都度buildコマンドを打つときに指定がいらないのでおすすめです。
①Buildコマンド時にプラットフォームを指定する
ECSにpushする際にbuildすると思いますが、build時のオプションで、下記コマンドのように使用するアーキテクチャを指定することができます。
docker build -t image-name --platform linux/x86_64 .
x86を指定してイメージをbuildすることで、FargateのCPUアーキテクチャにも対応できるようにします。
②Dockerfileでプラットフォームを指定する
DockerfileのFROMでイメージを指定する際に、ここでもオプションで、アーキテクチャを指定することができます。
FROM --platform=linux/x86_64 ruby:3.1.2
上記であればbuildした際に常にx86でイメージを作成してくれる為、少し楽になるかと思います。
終わりに
業務で初めてECSを使用したのですが、そもそもDocker自体の知識が少ないこともあり色々と苦戦しました...
今回のケースのように普段は見ることのないようなエラーに度々直撃し、先輩の助けを借り、なんとか調べながら実装までこじつけました。苦労をした分学ぶことも非常に多かったので、今回のケースに限らず別途記事を作成していきたいなと思っています。
Discussion