에러 로그
The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8)
문제 상황
지금 제 프로젝트는 로컬에서 feature 브랜치를 파서 개발한 후
develop 브랜치로 merge 요청을 보내면 Github actions 이 실행되는 구조입니다.
Github actions 에서는 Docker 이미지를 빌드 후 hub 에 push 하고,
서버에 ssh 로 접속해 방금 push 한 이미지를 pull 받은 후 docker compose up 을 실행합니다.
이때 정상적으로 빌드해서 push 한 이미지가 서버에서는 run 되지 않는 이슈가 있었습니다.

현재 프로젝트의 개발서버는 제 자취방에 마련해둔 라즈베리파이로 운영중이었는데,
로그를 보면 알 수 있듯 이미지의 platform 이 host 의 platform 과 다르다는 게 그 이유였습니다.
생각해보니 윈도우에서 빌드한 이미지가 M1 맥북에서 돌아가지 않았어서 옵션을 줬던 기억이..
아무튼 이유는
“라즈베리파이는 ARM 아키텍쳐라 Docker 이미지를 만든 Actions 환경과 달라서” 였습니다.
해결 방법
그렇다면 어떻게 해결하면 될까요 ?
1. 배포 환경과 동일한 이미지 빌드용 서버를 구축하기.
직관적인 방법이지만, 여러 프로세서 환경에서 배포해야 한다면 이를 위한 빌드 서버도
개수만큼 구축해주어야 합니다.
(아니 돈 아끼려고 라베파 쓰는 중인데)
2. docker buildx 로 멀티 platform 빌드
buildx 를 이용하면 간단하게 여러 다른 플랫폼 용으로 빌드가 가능합니다.
build 시에 —platform 플래그를 이용해서 빌드 출력의 대상 플랫폼을 지정할 수 있습니다.
주의해야 할점은 Docker engine 19.03 이상 버전에서 지원된다는 점입니다.
https://github.com/docker/buildx
GitHub - docker/buildx: Docker CLI plugin for extended build capabilities with BuildKit
Docker CLI plugin for extended build capabilities with BuildKit - GitHub - docker/buildx: Docker CLI plugin for extended build capabilities with BuildKit
github.com
저는 따로 빌드용 서버를 구축하기보다는 2번 방법을 선택했고,
Actions CI 환경에서 적용하기 위해서 workflow 파일을 수정했습니다.
아래는 기존에 사용하던 Actions workflow 파일의 일부입니다.
- name: Docker build
run: |
DATE=$(date "+%y.%m.%d")
docker build -t ${{ secrets.DOCKER_REPO }}/mineme-api:$DATE .
- name: Docker push
run: |
DATE=$(date "+%y.%m.%d")
docker push ${{ secrets.DOCKER_REPO }}/mineme-api:$DATE
buildx 를 이용해서 멀티 플랫폼 빌드를 하기 위해 아래처럼 수정했습니다.
Buildx 로 빌드하기 전에 QEMU 와 Buildx 를 setup 하고 진행하는데,
QEMU 는 다른 아키텍처에서 작성된 어플리케이션을, 원하는 환경에서 동작할 수 있게
명령어를 변환해주는 에뮬레이터라고 생각하시면 됩니다.
# https://github.com/docker/setup-qemu-action
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
# https://github.com/docker/setup-buildx-action
# docker buildx 설치
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Docker build
run: |
DATE=$(date "+%y.%m.%d")
docker buildx build --platform -t ${{ secrets.DOCKER_REPO }}/mineme-api:$DATE .
- name: Docker push
run: |
DATE=$(date "+%y.%m.%d")
docker push ${{ secrets.DOCKER_REPO }}/mineme-api:$DATE
만약 동일한 태그의 이미지가 이미 서버에 pull 되어 있다면, 지워주시고 진행하시면 됩니다.