docker manifestコマンドの確認

## はじめに

docker manifestコマンドを使ってamd64/arm64それぞれでイメージを同じタグで管理できるか確認した内容を記載する

https://docs.docker.com/reference/cli/docker/manifest/


## 実施環境

- Ubuntu 24.04, x86_64
- Docker 26.1.0

## QEMUのインストール

ARM環境を疑似するためにQEMUを使うためインストールしておく

```shell: コマンド
$ docker run --privileged --rm tonistiigi/binfmt --install all
```

## Docker Private Registry構築

docker imageの格納先となるPrivate Registryを構築する。

```shell: コマンド
$ docker run -d --name docker-registry -p 5000:5000 registry
```

## amd64/arm64のコンテナイメージ作成

docker buildコマンドで、amd64とarm64向けのイメージをビルドする。

:::note info
--platformオプションで各アーキの指定をしてビルドする
:::

```shell: コマンド
$ vi Dockerfile
$ docker buildx build --platform linux/amd64 --no-cache -t localhost:5000/test:1.0-amd64 --load .
$ docker buildx build --platform linux/arm64 --no-cache -t localhost:5000/test:1.0-arm64 --load .
```

```dockerfile: Dockerfile
# syntax=docker/dockerfile:1
FROM --platform=$BUILDPLATFORM golang:alpine AS build
ARG TARGETPLATFORM
ARG BUILDPLATFORM
RUN echo "I am running on $BUILDPLATFORM, building for $TARGETPLATFORM" > /log
FROM alpine
COPY --from=build /log /log
```

ビルド後、amd64とarm64のイメージが作成されていることを確認しておく

```shell: 実行結果
ubuntu@ubuntu:~/docker$ docker images
REPOSITORY            TAG         IMAGE ID       CREATED          SIZE
localhost:5000/test   1.0-arm64   6117b999211d   40 seconds ago   8.83MB
localhost:5000/test   1.0-amd64   fb6deceeb709   46 seconds ago   7.79MB
registry              latest      d6b2c32a0f14   7 months ago     25.4MB
tonistiigi/binfmt     latest      354472a37893   21 months ago    60.2MB
ubuntu@ubuntu:~/docker$
ubuntu@ubuntu:~/docker$ docker inspect localhost:5000/test:1.0-amd64 | jq .[].Architecture
"amd64"
ubuntu@ubuntu:~/docker$
ubuntu@ubuntu:~/docker$ docker inspect localhost:5000/test:1.0-arm64 | jq .[].Architecture
"arm64"
ubuntu@ubuntu:~/docker$
```

イメージが確認できたら、Private Registryにpushする。

```shell: コマンド
$ docker push localhost:5000/test:1.0-amd64
$ docker push localhost:5000/test:1.0-arm64
```

## manifestの作成とpush

amd64とarm64のイメージをtest:1.0というタグのマニフェストに紐づける。

```shell: コマンド
$ docker manifest create --insecure localhost:5000/test:1.0 \
                                    localhost:5000/test:1.0-amd64 \
                                    localhost:5000/test:1.0-arm64
$ docker manifest push localhost:5000/test:1.0
```

:::note info
docker manifest inspectコマンドで作成したmanifestが確認できる

```shell: 実行結果
ubuntu@ubuntu:~/docker$ docker manifest inspect --insecure localhost:5000/test:1.0
{
   "schemaVersion": 2,
   "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
   "manifests": [
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 734,
         "digest": "sha256:c663c587e22331baeeda4f1e2901c4a7cbc686a780cc15fd2d86f550f319bdd5",
         "platform": {
            "architecture": "amd64",
            "os": "linux"
         }
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 734,
         "digest": "sha256:b1d55ed3a44e92cd76636b9449563e5a9838a9187463e0f82cbe499244f5cdad",
         "platform": {
            "architecture": "arm64",
            "os": "linux"
         }
      }
   ]
}
ubuntu@ubuntu:~/docker$
```
:::


## 動作確認

動作確認前にローカルの情報を削除しておく。

```shell: コマンド
$ docker manifest rm localhost:5000/test:1.0
$ docker rmi localhost:5000/test:1.0-amd64 localhost:5000/test:1.0-arm64
```

amd64環境でtest:1.0タグをpullすると、amd64イメージが取得できることを確認する。
docker imagesコマンドで確認すると、IMAGE IDがamd64向けのものになっている。

```shell: 実行結果
ubuntu@ubuntu:~/docker$ docker run --rm --platform linux/amd64 localhost:5000/test:1.0 uname -m
Unable to find image 'localhost:5000/test:1.0' locally
1.0: Pulling from test
d25f557d7f31: Already exists
6865ecb6b0b7: Already exists
Digest: sha256:ebe948ab903fc230755ca1b17d7d0fdf1694445155bee77e4ddd2eb0646f43ac
Status: Downloaded newer image for localhost:5000/test:1.0
x86_64
ubuntu@ubuntu:~/docker$ docker images
REPOSITORY            TAG       IMAGE ID       CREATED         SIZE
localhost:5000/test   1.0       fb6deceeb709   6 minutes ago   7.79MB    
registry              latest    d6b2c32a0f14   7 months ago    25.4MB
tonistiigi/binfmt     latest    354472a37893   21 months ago   60.2MB
ubuntu@ubuntu:~/docker$
```

arm64環境でtest:1.0タグをpullすると、arm64イメージが取得できることを確認する。
docker imagesコマンドで確認すると、IMAGE IDがarm64向けのものになっている。

```shell: 実行結果
ubuntu@ubuntu:~/docker$ docker run --rm --platform linux/arm64 localhost:5000/test:1.0 uname -m
Unable to find image 'localhost:5000/test:1.0' locally
1.0: Pulling from test
94747bd81234: Already exists
c78bfcd53dae: Already exists
Digest: sha256:ebe948ab903fc230755ca1b17d7d0fdf1694445155bee77e4ddd2eb0646f43ac
Status: Downloaded newer image for localhost:5000/test:1.0
aarch64
ubuntu@ubuntu:~/docker$ docker images
REPOSITORY            TAG       IMAGE ID       CREATED         SIZE
localhost:5000/test   1.0       6117b999211d   7 minutes ago   8.83MB
localhost:5000/test   <none>    fb6deceeb709   7 minutes ago   7.79MB
registry              latest    d6b2c32a0f14   7 months ago    25.4MB
tonistiigi/binfmt     latest    354472a37893   21 months ago   60.2MB
ubuntu@ubuntu:~/docker$
```