GithubActions - ERROR: failed to solve: process "/dev/.buildkit_qemu_emulator... 해결하기
작성 일자 : 2024년 12월 19일
(이미지)
어떤 문제가 발생했는가?
발단: Github Actions에서 NextJS Docker 이미지 빌드
docker buildx build --platform linux/arm64 -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG . --push -f $DOCKER_FILE
에러 메시지
prod.Dockerfile:30
--------------------
29 |
30 | >>> RUN \
31 | >>> if [ -f yarn.lock ]; then yarn run build; \
32 | >>> elif [ -f package-lock.json ]; then npm run build; \
33 | >>> elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \
34 | >>> else echo "Lockfile not found." && exit 1; \
35 | >>> fi
36 |
--------------------
ERROR: failed to solve: process "/dev/.buildkit_qemu_emulator /bin/sh -c if [ -f yarn.lock ]; then yarn run build; elif [ -f package-lock.json ]; then npm run build; elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; else echo \"Lockfile not found.\" && exit 1; fi" did not complete successfully: exit code: 1
무엇을 하고 있었는가?
Answer: NextJS 프로젝트 ECS 배포 및 Github Actions을 통한 CI/CD 파이프라인 구축
배포 환경
- AWS ECS
arm64
아키텍처 기반 EC2 인스턴스 (t4g.small
)- GithubActions에서
docker buildx
를 통한 멀티 아키텍처 이미지 빌드 진행
deploy.yml
name: Deploy Spring Boot to Amazon ECS
on:
push:
branches: ["main"]
workflow_dispatch:
env:
DOCKER_FILE: prod.Dockerfile
AWS_REGION: ${{ secrets.AWS_REGION }}
ECR_REPOSITORY: ${{ secrets.FRONTEND_ECR_REPOSITORY }}
ECS_SERVICE: ${{ secrets.FRONTEND_ECS_SERVICE }}
ECS_CLUSTER: ${{ secrets.FRONTEND_ECS_CLUSTER }}
ECS_TASK_DEFINITION: ${{ secrets.FRONTEND_ECS_TASK_DEFINITION }}
CONTAINER_NAME: ${{ secrets.FRONTEND_CONTAINER_NAME }}
CODEDEPLOY_APPLICATION: ${{ secrets.FRONTEND_CODEDEPLOY_APPLICATION }}
CODEDEPLOY_DEPLOYMENT_GROUP: ${{ secrets.FRONTEND_CODEDEPLOY_DEPLOYMENT_GROUP }}
jobs:
ecs-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Make .env
run: |
touch .env
echo "${{ secrets.FRONTEND_ENV }}" > .env
shell: bash
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ${{ env.AWS_REGION }}
aws-access-key-id: ${{ secrets.FRONTEND_AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.FRONTEND_AWS_SECRET_ACCESS_KEY }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Build, tag, and push image to Amazon ECR
id: build-image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
IMAGE_TAG: ${{ github.sha }}
run: |
docker buildx create --name multi-arch-builder --driver docker-container --bootstrap --use
docker buildx build --platform linux/arm64 -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG . --push -f $DOCKER_FILE
echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT
- name: Download Amazon ECS task definition
env:
TASK_DEFINITION_NAME: ${{ env.ECS_TASK_DEFINITION }}
run: |
aws ecs describe-task-definition --task-definition $TASK_DEFINITION_NAME --query taskDefinition > task-definition.json
- name: Fill in the new image ID in the Amazon ECS task definition
id: task-def
uses: aws-actions/amazon-ecs-render-task-definition@v1
with:
task-definition: task-definition.json
container-name: ${{ env.CONTAINER_NAME }}
image: ${{ steps.build-image.outputs.image }}
- name: Deploy Amazon ECS task definition
uses: aws-actions/amazon-ecs-deploy-task-definition@v2
with:
task-definition: ${{ steps.task-def.outputs.task-definition }}
service: ${{ env.ECS_SERVICE }}
cluster: ${{ env.ECS_CLUSTER }}
wait-for-service-stability: false
codedeploy-appspec: appspec.yml
codedeploy-application: ${{ env.CODEDEPLOY_APPLICATION }}
codedeploy-deployment-group: ${{ env.CODEDEPLOY_DEPLOYMENT_GROUP }}
prod.Dockerfile
FROM node:18-alpine AS base
# Install dependencies only when needed
FROM base AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk add --no-cache libc6-compat
WORKDIR /app
# Install dependencies based on the preferred package manager
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* .npmrc* ./
RUN \
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
elif [ -f package-lock.json ]; then npm ci; \
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \
else echo "Lockfile not found." && exit 1; \
fi
# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
# Next.js collects completely anonymous telemetry data about general usage.
# Learn more here: https://nextjs.org/telemetry
# Uncomment the following line in case you want to disable telemetry during the build.
# ENV NEXT_TELEMETRY_DISABLED 1
RUN \
if [ -f yarn.lock ]; then yarn run build; \
elif [ -f package-lock.json ]; then npm run build; \
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \
else echo "Lockfile not found." && exit 1; \
fi
# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app
ENV NODE_ENV production
# Uncomment the following line in case you want to disable telemetry during runtime.
ENV NEXT_TELEMETRY_DISABLED 1
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
COPY --from=builder /app/public ./public
# Set the correct permission for prerender cache
RUN mkdir .next
RUN chown nextjs:nodejs .next
# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT 3000
# server.js is created by next build from the standalone output
# https://nextjs.org/docs/pages/api-reference/next-config-js/output
ENV HOSTNAME="0.0.0.0"
CMD ["node", "server.js"]
어떻게 해결하였는가?
Answer: deploy.yml
스크립트에서 Set up QEMU
과정 추가
Set up QEMU
Github Actions 사용 예시
name: ci
on:
push:
jobs:
qemu:
runs-on: ubuntu-latest
steps:
-
name: Set up QEMU
uses: docker/setup-qemu-action@v3
deploy.yml
변경된 부분
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Set up QEMU # docker buildx build 이전에 Set up QEMU 과정 추가
uses: docker/setup-qemu-action@v3
- name: Build, tag, and push image to Amazon ECR
id: build-image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
IMAGE_TAG: ${{ github.sha }}
run: |
docker buildx create --name multi-arch-builder --driver docker-container --bootstrap --use
docker buildx build --platform linux/arm64 -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG . --push -f $DOCKER_FILE
...
Reference
- Github Actions - Set up QEMU
- Stackoverflow - How to install qemu emulator for arm in a docker container
- Github Issue - failed running [/dev/.buildkit_qemu_emulator /bin/sh -c which ls]: exit code: 127
failed running [/dev/.buildkit_qemu_emulator /bin/sh -c which ls]: exit code: 127 · Issue #464 · docker/buildx
First of all thank you for your work, buildx is very important to me Today I found that I kept failing when trying to build an arm64 images on x86 machine, so I tried to make a simple enough image ...
github.com
How to install qemu emulator for arm in a docker container
My goal is to build a Docker Build image that can be used as a CI stage that's capable of building a multi-archtecture image. FROM public.ecr.aws/docker/library/docker:20.10.11-dind # Add the buildx
stackoverflow.com
Docker Setup QEMU - GitHub Marketplace
Install QEMU static binaries
github.com