티스토리 뷰

 

[CI&CD] Spring boot 프로젝트를 Docker와 Github Action이용해서 자동배포하기

대략적인 그림은 이와 같다. 1. Dockerfile 작성 먼저, Dockerfile을 작성한다. Dockerfile은 Docker이미지를 빌드하기 위한 지시문을 포함한다. FROM openjdk:11-jdk ARG JAR_FILE=./build/libs/dashboardback-0.0.1-SNAPSHOT.jar CO

minsu20.tistory.com

지난 게시글에서 나는 Secrets에 application.yml파일을 넣고 Github-Actions시에 그걸 생성해서 build하였다. 이번에도 그렇게 CI/CD를 구성하고 firebase-key.json도 secrets에 넣어서 applicaton.yml과 같이 생성해서 src/main/resources안에 두개를 넣어서 build하였다. 

name: Java CI with Gradle
on:
  push:
    branches: [ master ]       

jobs:
  build:                    
    runs-on: ubuntu-latest    
    env :
      working-directory: ./
      APPLICATION: ${{ secrets.APPLICATION }}
      GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
      
    steps:
    - name: Checkout repository
      uses: actions/checkout@v2

    - name: Set up JDK 11
      uses: actions/setup-java@v2
      with:
        java-version: '11'
        distribution: 'adopt'
        
    - name: Cache Gradle packages
      uses: actions/cache@v2
      with:
        path: |
             ~/.gradle/caches
             ~/.gradle/wrapper
        key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
        restore-keys: |
              ${{ runner.os }}-gradle-
  
    - uses: actions/checkout@v2
    - run: mkdir -p ./src/main/resources
    - run: touch ./src/main/resources/application.yml
    - run: echo "${{env.APPLICATION}}" > ./src/main/resources/application.yml
    - uses: actions/upload-artifact@v2
      with:
        name: application.yml
        path: ./src/main/resources/application.yml
    - run: touch ./src/main/resources/firebase-key.json
    - run: echo "${{env.GOOGLE_APPLICATION_CREDENTIALS}}" | base64 --decode > ./src/main/resources/firebase-key.json
    - uses: actions/upload-artifact@v2
      with:
        name: firebase-key.json
        path: ./src/main/resources/firebase-key.json
        
        
    - name: Grant execute permission for gradlew
      run: chmod +x gradlew
      working-directory: ${{ env.working-directory }}
      
    - name: Build with Gradle
      run: ./gradlew build
      working-directory: ${{ env.working-directory }}
      
    - name: Cleanup Gradle Cache
      if: ${{ always() }}
      run: |
          rm -f ~/.gradle/caches/modules-2/modules-2.lock
          rm -f ~/.gradle/caches/modules-2/gc.properties
    - name: Docker build and push
      run: |
          docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
          docker build -t ${{ secrets.PROJECT_NAME }} .
          docker tag ${{ secrets.PROJECT_NAME }} ${{ secrets.DOCKER_HUB_REPO }}:${GITHUB_SHA::7}
          docker push ${{ secrets.DOCKER_HUB_REPO }}:${GITHUB_SHA::7}
    - name: Deploy application to WAS instance
      uses: appleboy/ssh-action@v0.1.6
      with:
        host: ${{ secrets.EC2_SERVER_HOST }}
        username: ec2-user
        key: ${{ secrets.PRIVATE_KEY }}
        envs: GITHUB_SHA
        script: |
            docker rmi $(docker images -q)
            docker pull ${{ secrets.DOCKER_HUB_REPO }}:${GITHUB_SHA::7}
            docker tag ${{ secrets.DOCKER_HUB_REPO }}:${GITHUB_SHA::7} ${{ secrets.PROJECT_NAME }}
            docker stop ${{ secrets.PROJECT_NAME }}
            docker rm ${{ secrets.PROJECT_NAME }}
            docker run -d --name ${{ secrets.PROJECT_NAME }} -p 80:8080 ${{ secrets.PROJECT_NAME }}

그런데 문제가 발생했다! 

 

계속해서 application.yml파일과 firebase-key.json파일을 찾을 수 없다고 뜨는 거다. ㅠ..ㅠ...

 

 

수 많은 커밋을 하면서... 이대로 버그를 못 잡나 좌절을 하고 있을 때... gpt 선생님이 조언을 해주셨다...

????? 해결 방안이 보인 것 같아서 더 자세하게 물어보았다.

 

firebase-key.json 파일이 없는 에러가 발생하는 이유는, GitHub Actions에서 생성한 Docker 이미지가 해당 파일을 포함하지 않기 때문이었다. 이를 해결하기 위해서는 Docker 이미지 빌드 과정에서 해당 파일을 이미지에 포함시켜주어야 한다. 

해당 GitHub Actions workflow 파일에서 Docker build and push 단계를 보면, docker build 명령어를 사용하여 Docker 이미지를 빌드하고 있으므로 이 명령어에 --build-arg 옵션을 사용하여 firebase-key.json 파일 경로를 Docker 빌드 컨텍스트에 전달해주고, Dockerfile에서 이를 사용하여 이미지에 파일을 포함시킬 수 있다. 

 

1. Dockerfile 수정

FROM openjdk:11-jdk
# Add firebase-key.json
ARG FIREBASE_KEY_PATH
COPY ${FIREBASE_KEY_PATH} src/main/resources/firebase-key.json

ARG JAR_FILE=./build/libs/BE-0.0.1-SNAPSHOT.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

2. actions.yml 수정

위 파일에서 Docker build 하는 부분만 다음과 같이 수정한다.

    - name: Docker build and push
      env:
        FIREBASE_KEY_PATH: src/main/resources/firebase-key.json

      run: |
          docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
          docker build -t ${{ secrets.PROJECT_NAME }} \
            --build-arg FIREBASE_KEY_PATH=${FIREBASE_KEY_PATH} \
            --build-arg JAR_FILE=./build/libs/BE-0.0.1-SNAPSHOT.jar \
            .
          docker tag ${{ secrets.PROJECT_NAME }} ${{ secrets.DOCKER_HUB_REPO }}:${GITHUB_SHA::7}
          docker push ${{ secrets.DOCKER_HUB_REPO }}:${GITHUB_SHA::7}

핵심은 --build-arg 요 부분!!

 

성공 ^^!!