はじめに

システム開発において、Docker を利用している方は多いのではないでしょうか。

Docker イメージは可搬性に優れており、検証環境でビルドしたイメージを本番環境に持ち込むことで、同一のアプリケーション実行環境を再現できます。

これにより、「環境差異による不具合」を減らせる点が、コンテナ技術の大きな強みです。

ただし、この可搬性は万能ではありません。

CPUアーキテクチャ(例:x86_64 と arm64)によっては、同一イメージでも動作しない場合があります。

そのため、「イメージさえあればどこでも同じように動く」という理解ではなく、実行環境との整合性を意識した運用が重要になります。

2. 本記事の結論

CPUアーキテクチャが一致しないとコンテナは起動できないです。

対策は、アーキテクチャを揃える or マルチアーキテクチャ対応が必要です。

3. 検証環境

3.1 ビルド環境

  • OS
    • Amazon Linux 2
  • インスタンスタイプ
    • t3.micro

3.2. コンテナ起動環境

  • OS
    • Amazon Linux 2023
  • インスタンスタイプ
    • t4g.micro

4. Dockerイメージのビルドとpush

4.1. CPU アーキテクチャの確認

sh-4.2$ uname -m
x86_64

4.2. Docker から ECR にログインする

sh-4.2$ aws ecr get-login-password --region us-west-2 | docker login --username AWS --password-stdin xxxxxxxxxx.dkr.ecr.us-west-2.amazonaws.com
WARNING! Your password will be stored unencrypted in /home/ssm-user/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded

4.3. ビルド実施

sh-4.2$ sudo docker build -t cpu-arch-test .
[+] Building 3.3s (5/5) FINISHED                                                                                                                                                                                                                       docker:default
 => [internal] load build definition from Dockerfile                                                                                                                                                                                                             0.0s
 => => transferring dockerfile: 125B                                                                                                                                                                                                                             0.0s
 => [internal] load metadata for docker.io/library/
 〜以下、略〜

4.4. イメージにタグを付与する

sh-4.2$ sudo docker tag cpu-arch-test:latest xxxxxxxxxxxxx.dkr.ecr.us-west-2.amazonaws.com/cpu-arch-test:latest

4.5. ECR にイメージをプッシュする

sh-4.2$ sudo docker push xxxxxxxxxxxxx.dkr.ecr.us-west-2.amazonaws.com/cpu-arch-test:latest
The push refers to repository [xxxxxxxxxxxxx.dkr.ecr.us-west-2.amazonaws.com/cpu-arch-test]
3baf45fb4b5e: Pushed
538812a4b9bd: Pushed
latest: digest: sha256:84d1632a2780f1e78d0857d90ce20707cda6b0b7d817ed52fb25c09e8dfd6057 size: 742

5. 別環境でpullして実行

5.1. CPU アーキテクチャを確認

sh-5.2$ uname -m
aarch64

5.2. Docker から ECR にログインする

sh-5.2$ aws ecr get-login-password --region us-west-2 | \
sudo docker login \
  --username AWS \
  --password-stdin xxxxxxxxxxxxx.dkr.ecr.us-west-2.amazonaws.com
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

5.3. ECR からイメージを Pull する

sh-5.2$ sudo docker pull xxxxxxxxxxxxx.dkr.ecr.us-west-2.amazonaws.com/cpu-arch-test:latest
latest: Pulling from cpu-arch-test
2f7571f14c6f: Pull complete
04f0c7cfe47b: Pull complete
Digest: sha256:84d1632a2780f1e78d0857d90ce20707cda6b0b7d817ed52fb25c09e8dfd6057
Status: Downloaded newer image for xxxxxxxxxxxxx.dkr.ecr.us-west-2.amazonaws.com/cpu-arch-test:latest
xxxxxxxxxxxxx.dkr.ecr.us-west-2.amazonaws.com/cpu-arch-test:latest

5.4. コンテナを起動する

exec /bin/bash: exec format error というエラーが出力され、コンテナの起動ができない。

sh-5.2$ sudo docker run -it xxxxxxxxxxxxx.dkr.ecr.us-west-2.amazonaws.com/cpu-arch-test:latest
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
exec /bin/bash: exec format error

6. 原因

コンテナの起動しようとすると exec /bin/bash: exec format error というエラーが出力されました。

2. 本記事の結論 で述べた通り、ビルド環境とコンテナ起動環境の「CPUアーキテクチャが一致しない」場合、exec /bin/bash: exec format error が発生します。

7. イメージの対応している CPU アーキテクチャ確認方法

docker inspect <イメージID> でイメージがビルドされた環境を確認することができます。

amd64 の CPU アーキテクチャでのみ利用できます。

sh-5.2$ sudo docker inspect 3857ffd955b8
[
    {
        "Id": "sha256:3857ffd955b84f26942b70dd3758f043e1eefeb3d328dad6decbb96c88751872",
        "RepoTags": [
            "730335414536.dkr.ecr.us-west-2.amazonaws.com/cpu-arch-test:latest"
        ],
        "RepoDigests": [
            "730335414536.dkr.ecr.us-west-2.amazonaws.com/cpu-arch-test@sha256:84d1632a2780f1e78d0857d90ce20707cda6b0b7d817ed52fb25c09e8dfd6057"
~~~~~~中略~~~~~~
        "Architecture": "amd64", ★このイメージは、「amd64」でビルドされている。
        "Os": "linux", ★このイメージは、「linix」でビルドされている。
        "Size": 511986239,
~~~~~~中略~~~~~~
]

"Architecture": "amd64" と記述されているので、このイメージは、 amd64 の CPU アーキテクチャでのみ利用できるということになります。

8. マルチアーキテクチャ対応イメージについて

ここまで、Dockerイメージは対応したCPUアーキテクチャでのみ実行できると説明しました。

しかし、異なるアーキテクチャ環境でも同一のイメージタグでコンテナを実行できる仕組みが存在します。それが「マルチアーキテクチャ対応イメージ」です。

マルチアーキテクチャ対応のイメージは、イメージタグに複数のアーキテクチャのイメージが紐付いており、ホストの環境にあったイメージを自動的に利用します。

マルチアーキテクチャ対応のイメージであるか確認する方法は、docker manifest inspect <イメージ名> を利用することで確認することができます。

sh-5.2$ sudo docker manifest inspect nginx
{
   "schemaVersion": 2,
   "mediaType": "application/vnd.oci.image.index.v1+json",
   "manifests": [
      {
         "mediaType": "application/vnd.oci.image.manifest.v1+json",
         "size": 2290,
         "digest": "sha256:296499281873ebe2636681c6957776d29a31858d93c3e39b654b5aade87ed70a",
         "platform": {
            "architecture": "amd64", ★対応アーキテクチャ
            "os": "linux"
         }
      },
~~~~~~中略~~~~~~
      {
         "mediaType": "application/vnd.oci.image.manifest.v1+json",
         "size": 2290,
         "digest": "sha256:39d28f84ac5f308718a9649e15df444cf7af254fab03018c614c615803eb308b",
         "platform": {
            "architecture": "s390x", ★対応アーキテクチャ
            "os": "linux"
         }
      }
   ]
}

9. 解決方法

exec /bin/bash: exec format error が発生した場合の解決方法は以下のとおりです。

※ この記事ではマルチアーキテクチャビルド方法については割愛させていただきます。

9.1. 実行環境と同じアーキテクチャでイメージをビルドする

最もシンプルな方法は、イメージのビルド環境と実行環境のCPUアーキテクチャを揃えることです。

以下のコマンドでホストのアーキテクチャを確認できます。

uname -m

また、Dockerイメージのアーキテクチャは以下で確認可能です。

docker image inspect <image> --format '{{.Os}}/{{.Architecture}}'

両者が一致していることを確認してください。

9.2. ビルド時にアーキテクチャを明示的に指定する

ビルド環境と実行環境が異なる場合、–platform オプションを利用することで、ターゲットのアーキテクチャを指定してイメージを作成できます。

docker build --platform linux/amd64 -t cpu-arch-test .

10. まとめ

本記事では、Dockerコンテナ実行時に発生する exec format error の原因と対処方法について解説しました。

  • DockerイメージはCPUアーキテクチャに依存する
  • 実行環境とイメージのアーキテクチャが一致しない場合、コンテナは起動できない
  • マルチアーキテクチャ対応イメージを利用することで、環境差異を吸収できる

Dockerは環境差異を減らす強力なツールですが、CPUアーキテクチャの違いまでは完全に抽象化できません。 そのため、イメージのビルド戦略や実行環境を意識した設計が重要になります。