에러 로그
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
저는 따로 빌드용 서버를 구축하기보다는 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 되어 있다면, 지워주시고 진행하시면 됩니다.