アプリ開発備忘録

PlayStationMobile、Android、UWPの開発備忘録

dockerでマルチプラットフォーム用にビルドして1つのタグにまとめる。

arm64とamd64向けにビルドを行い、Manifestを使用して1つのtagで、使用するプラットフォームごとに自動的にアーキテクチャを選択させます。
今回はリポジトリとしてECRを使用しています。

まずは色々定義します。
ベースの名前を決めます。あとはプラットフォームごとのタグも決めます。末尾に -amd64 -arm64 を付けました。

ECR_REMOTE_URL="000000000000.dkr.ecr.ap-northeast-1.amazonaws.com"
REMOTE_REPO_NAME="repo_name"

TAG="tag_name"
REMOTE_MANIFEST_URI=${ECR_REMOTE_URL}/${REMOTE_REPO_NAME}:${TAG}
REMOTE_AMD64_URI=${ECR_REMOTE_URL}/${REMOTE_REPO_NAME}:${TAG}-amd64
REMOTE_ARM64_URI=${ECR_REMOTE_URL}/${REMOTE_REPO_NAME}:${TAG}-arm64

LOCAL_AMD64_URI=local_repo_name:${TAG}-amd64 
LOCAL_ARM64_URI=local_repo_name:${TAG}-arm64 

buildxを準備します。CircleCIではローカルとは違う手順が必要でした。
https://support.circleci.com/hc/en-us/articles/360058095471-How-To-Use-Docker-Buildx-in-Remote-Docker-

echo "========== preparate buildx =========="
if $CIRCLECI ;then
    docker context create buildx-build
    docker buildx create --use buildx-build --name amd-arm --driver docker-container --platform linux/arm64,linux/amd64
else
    docker buildx create --name amd-arm --driver docker-container --platform linux/arm64,linux/amd64
fi

プラットフォームはカンマ区切りで複数選択できますが、 --load でDockerに出力はできません。
複数選択して、 --load をしないと、キャッシュにだけ残ります。

echo "========== build image =========="
docker buildx build --builder amd-arm --platform linux/amd64 -t $LOCAL_AMD64_URI --load .
docker buildx build --builder amd-arm --platform linux/arm64 -t $LOCAL_ARM64_URI --load .

ECRにログインしてそれぞれのアーキテクチャのimageをpushします。

echo "========== push image =========="
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin ${ECR_REMOTE_URL}

docker tag $LOCAL_AMD64_URI $REMOTE_AMD64_URI
docker tag $LOCAL_ARM64_URI $REMOTE_ARM64_URI

docker push ${REMOTE_AMD64_URI}
docker push ${REMOTE_ARM64_URI}

最初の引数にマニフェストの名前を、続いて関連付けたいマニフェストを記述します。先にimageをpushしておく必要があります。
その後にイメージに対してどのアーキテクチャかを教えます。
docker manifest inspect で中身のjsonを確認できます。

echo "========== create manifest =========="
docker manifest create ${REMOTE_MANIFEST_URI} \
    ${REMOTE_AMD64_URI}  \
    ${REMOTE_ARM64_URI}
    
docker manifest annotate --arch amd64 ${REMOTE_MANIFEST_URI} $REMOTE_AMD64_URI
docker manifest annotate --arch arm64 ${REMOTE_MANIFEST_URI} $REMOTE_ARM64_URI

docker manifest inspect ${REMOTE_MANIFEST_URI}

後はpushすればおしまいです。

echo "========== push manifest =========="
docker manifest push ${REMOTE_MANIFEST_URI}

ECRではこのような表示になっています。後はこのタグ名を指定して使用します。