본문 바로가기
Infra

Docker in Docker 문제

by 고선제 2024. 9. 4.

상황

  1. 테스트 환경에서 h2 in-memory db를 사용하다가 mysql로 변경하기 위해 TestContainer를 도입하였다.
  2. TestContainer 설정 이후 CI가 될 때, TestContainer를 이용한 테스트들이 모두 에러가 났다.

 

→ CI 환경에서 테스트 시 발생하는 에러이다.

에러 발생 이유

  • Docker In Docker
    • 말 그대로 Docker Engine으로 실행한 컨테이너 안에서 또 다시 Docker에서 TestContainer를 실행시키기 위해 명령어를 사용했기에 발생한 에러이다.
    • 에러가 발생한 CI 스크립트는 다음과 같다.
    name: Develop Server Integrator (CI)
    
    on:
      push:
        branches:
          - develop
    
    jobs:
      build_and_push:
        runs-on: ubuntu-latest
        steps:
          - name: Check Out Repository
            uses: actions/checkout@v4
    
          - name: Configure AWS Credentials
            uses: aws-actions/configure-aws-credentials@v4
            with:
              aws-access-key-id: ${{ secrets.DEV_AWS_ACCESS_KEY_ID }}
              aws-secret-access-key: ${{ secrets.DEV_AWS_SECRET_ACCESS_KEY }}
              aws-region: us-east-1
    
          - name: Login to Amazon ECR Public
            id: login-ecr-public
            uses: aws-actions/amazon-ecr-login@v2
            with:
              registry-type: public
    
          - name: Build, tag, and push docker image to Amazon ECR Public
            env:
              REGISTRY: ${{ steps.login-ecr-public.outputs.registry }}
              REGISTRY_ALIAS: ${{ secrets.DEV_ECR_REGISTRY_ALIAS }}
              REPOSITORY: dev-ecr
              IMAGE_TAG: latest
            run: |
              echo "REPOSITORY: $REPOSITORY"
              docker build -t $REGISTRY/$REGISTRY_ALIAS/$REPOSITORY:$IMAGE_TAG .
              docker push $REGISTRY/$REGISTRY_ALIAS/$REPOSITORY:$IMAGE_TAG
              echo "::set-output name=image::$REGISTRY/$REGISTRY_ALIAS/$REPOSITORY:$IMAGE_TAG"
    
          - name: Logout of Amazon ECR
            run: docker logout ${{ env.ECR_REGISTRY }}
    
    → 문제가 발생한 곳은 Build, tag, and push docker image to Amazon ECR Public 여기이다.
    1. docker build 명령어를 입력하면 DockerFile을 사용하여 spring boot 파일을 이미지화 시킨다.→ 에러가 발생한 상황의 DockerFile이다.
    2. # Build stage FROM gradle:jdk17 AS build COPY --chown=gradle:gradle . /home/gradle/src WORKDIR /home/gradle/src RUN gradle build --no-daemon
    3. 이때, docker container 안에 빌드가 수행된다.
    4. docker container 안에서 gradle build --no-daemon 명령어로 인해 테스트가 이루어지는데, 테스트 실행시 Test Container를 사용하게된다.
    5. TestContainer는 다시 Docker의 명령어를 통해 이미지를 가져와야 하는데, 이때 Docker In Docker 문제가 발생하는 것이다.

해결 방법

  • 해결 방법은 생각보다 간단하다.
  • docker build를 통해 이미지화가 이루어질 때 테스트를 수행하지 않으면 된다.
  • build를 하기 전에 test를 수행하고 build할 때는 테스트를 수행하지 않아야 한다.

  1. build 전 Test를 수행한다.
# ..기존 내용

- name: CI Test
    run: ./gradlew clean test

- name: Configure AWS Credentials
  uses: aws-actions/configure-aws-credentials@v4
  with:
    aws-access-key-id: ${{ secrets.DEV_AWS_ACCESS_KEY_ID }}
    aws-secret-access-key: ${{ secrets.DEV_AWS_SECRET_ACCESS_KEY }}
    aws-region: us-east-1
- name: Login to Amazon ECR Public
  id: login-ecr-public
  uses: aws-actions/amazon-ecr-login@v2
  with:
    registry-type: public
- name: Build, tag, and push docker image to Amazon ECR Public
  env:
    REGISTRY: ${{ steps.login-ecr-public.outputs.registry }}
    REGISTRY_ALIAS: ${{ secrets.DEV_ECR_REGISTRY_ALIAS }}
    REPOSITORY: dev-ecr
    IMAGE_TAG: latest
  run: |
    echo "REPOSITORY: $REPOSITORY"
    docker build -t $REGISTRY/$REGISTRY_ALIAS/$REPOSITORY:$IMAGE_TAG .
    docker push $REGISTRY/$REGISTRY_ALIAS/$REPOSITORY:$IMAGE_TAG
  1. docker build 시 테스트 수행을 하지 않는다.
  2. FROM gradle:jdk17 AS build COPY --chown=gradle:gradle . /home/gradle/src WORKDIR /home/gradle/src RUN ./gradlew clean build -x test --no-daemon

해결!!!

'Infra' 카테고리의 다른 글

AWS Lambda 와 Mediaconvert 세팅 오류(feat. Log)  (1) 2025.01.25