TECHNICAL KNOWLEDGE BASE

[Azure] Github Actions를 통한 Spring Boot CI/CD 배포 - App Services(Linux)

GithubAction CICD Webapp SpringBoot Project 배포 LV : AZ 100 개요 img /assets/category/Azure/2023/07/27 00.png 1. Eclipse SpringBoot Project 생성 1. Spring

CI/CD
Azure

Legacy Engineering Note · 기존 기술 블로그에서 선별 이관한 기록입니다. 작성 당시 환경과 버전을 기준으로 합니다.

GithubAction CICD Webapp SpringBoot Project 배포

LV : AZ-100

개요

1. [Eclipse] SpringBoot Project 생성

  1. Spring Starter Project 실행

  2. Project 스펙 선택

    • Type : Gradle
    • Packaging : webapp은 기본적으로 Jar파일 배포, war도 배포 가능
    • Java Version : 17
      • AKS 배포이슈가 있음 아래와 같은 스펙으로 수정 필요
        • Java Version : 11
        • Gradle : 6.x.x, 기본생성시 8점대로 생성됨
    • Language : Java
  3. 필요한 의존성 추가하고 프로젝트 생성을 완료한다.

2. Github repository 생성

  1. Github에 로그인해서 아래 이미지와 같이 NEW를 클릭

  2. 이부분은 필요에 따라 다르게 설정하면 된다.

    • Repository name : 대표적인 타이틀로 적절하게 작성
    • Public으로 해도 괜찮다.
    • Add a README file : Git Branch가 어느날부터 master가 아닌 main으로 바뀌면서 기존 master로 사용하기 위해 별도의 수정이 필요해짐
    • 맨 아래 Create repository 클릭해서 생성 완료

3. Github Branch명 수정방법

  1. [Skip] Branch명 수정, View all branches 클릭

  2. [Skip] 우측 하단에 연필모양 클릭

  3. [Skip] main 대신 master를 입력하고 Rename branch 버튼을 클릭하면 완료

  4. 미리 Eclipse와 연동을 위해 Code를 클락하여 Repository 주소를 복사한다.

4. Eclipse Github 연동

  1. Git Repositories탭에서 Clone버튼 클릭

  2. 3-4번 과정을 수정했다면 아래와같이 정보가 인입될것이다. Next버튼을 눌러 진행

    [참고] 최근 Github 인증방식이 업데이트 되어 Authentication란의 Password를 토큰으로 받아 진행해야한다.

  3. 토큰이 만료됐거나 삭제 및 변동사항이 있는경우 아래처럼 창 하나가 뜬다.
    이 경우 재발행 할 것

5. Github Token 발행

  1. 깃허브 우측 상단에 프로필을 눌러 Settings으로 들어간다.

  2. Setting 화면 맨 아래에 있는 Developer settings로 들어간다.

  3. Tokens(classic)을 클릭해서 Generate new token으로 토큰발행 진행

  4. 기존 classic 방식으로 발행 권장

  5. 프로젝트 범위에 따라 scope범위를 지정 후 아래 Generate token을 클릭하여 완료

  6. Token은 단 한번만 보여주기 때문에 보관에 유의가 필요하다.

    잃어버린 경우 재발행 필요

    • 해당 토큰을 복사 후 3-3번 화면의 Password로 붙여넣어준다.
    • Store in Secure Store : 체크해서 반복적으로 묻지않도록 해줌

    • 로그인 성공했으면 Next를 눌러 로컬과 Github를 연동시킨다.

6. Project Github repository 연동

  1. 프로젝트 우클릭 > Team > Share Project 클릭

  2. 연결 할 repository 선택 후 Finish

7. Github repository에 프로젝트 업로드

  1. 프로젝트 우클릭 > Team > Commit 클릭

  2. ++버튼을 눌러 Staaged Changes상태로 올리고 Commit Message입력 후 Commit

  3. 프로젝트 확인

8. Azure Webapp 생성

  1. Azure Potal 접속 후 App Services 생성

    • 웹 앱 선택
  2. App Service 기본

    • 런타임 스택 : Java버전과 동일
    • Java 웹 서버 스택 :
      1. jar : SpringBoot 프로젝트는 서버를 내장형으로 탑재되어있어 Embedded Web Server로 선택
      2. war : JDK버전이 17인 경우 tomcat 10을 선택
    • 가격 책정 플랜 : 기본등급 이상으로 선택해야 Github와 연동 가능
  3. App Service 배포

    • Github Actions 설정 : 사용으로 선택
    • 조직, 리포지토리, 분기 : 자동배포할 프로젝트가 있는 repository를 선택 해 준다.
  4. 검토 + 만들기를 선택해서 리소스를 생성 한다.

9. workflow.yaml파일 수정

Github 저장소로 돌아가서 Action을 보게 되면 아래와 같이 이미 벌써 Action이 돌아가 프로젝트를 Build하는것을 볼 수 있다.
AppService를 생성하면서 자동으로 workflow까지 작성해주지만 수정해야할 부분이 있어 필요부분을 수정 해 준다.

  • 기존 workflow yaml파일
    # Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy
    # More GitHub Actions for Azure: https://github.com/Azure/actions
    
    name: Build and deploy JAR app to Azure Web App - CICDTest-as
    
    on:
      push:
        branches:
          - master
      workflow_dispatch:
    
    jobs:
      build:
        runs-on: ubuntu-latest
    
        steps:
          - uses: actions/checkout@v2
    
          - name: Set up Java version
            uses: actions/setup-java@v1
            with:
              java-version: '17'
    
          - name: Build with Maven
            run: mvn clean install
    
          - name: Upload artifact for deployment job
            uses: actions/upload-artifact@v2
            with:
              name: java-app
              path: '${{ github.workspace }}/target/*.jar'
    
      deploy:
        runs-on: ubuntu-latest
        needs: build
        environment:
          name: 'Production'
          url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}
    
        steps:
          - name: Download artifact from build job
            uses: actions/download-artifact@v2
            with:
              name: java-app
    
          - name: Deploy to Azure Web App
            id: deploy-to-webapp
            uses: azure/webapps-deploy@v2
            with:
              app-name: 'CICDTest-as'
              slot-name: 'Production'
              publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_D8DBFBB179E7449CA1D9745E0581E194 }}
              package: '*.jar'
    

9-1. jar 파일 yaml 작성

  1. Build에서 아래 사항대로 수정 진행

    1. Build with Maven 주석처리

    2. Gradle build에 필요한 권한 부여

    3. Gradle build 진행

      # 1. Build with Maven 주석처리
      # - name: Build with Maven
      #   run: mvn clean install
      
      # 2. Gradle build에 필요한 권한 부여
      - name: Grant execute permission for gradlew
        run: chmod +x gradlew
        working-directory: <프로젝트 폴더명>
      
      # 3. Gradle build 진행
      - name: Build with Gradle
        run : |
          cd <프로젝트 폴더명>     # 해당 디렉토리로 이동
          ./gradlew build -x test # Gradle 빌드 실행
      
    4. Upload artifact for deployment job에서 build된 파일경로 수정

      path부분을 artifact가 있는 위치로 수정

      • 수정 전

        path: '${{ github.workspace }}/target/*.jar'
        
      • 수정 후

        path: '${{ github.workspace }}/<프로젝트 폴더명> /build/libs/*SNAPSHOT.jar'
        
      • 해당 경로 부분에서 *. 지정하게 되면 프로젝트 빌드시 배포파일의 충돌로 인해 배포오류가 발생한다.

      • plain.jar와 SNAPSHOT.jar파일 두가지가 생성되기 때문에 plain이 아닌 파일로 지정해서 충돌을 피해준다.

  2. deploy 단계에서 마지막 jar파일의 경로 수정

    • package를 plain.jar와 충돌되지 않도록 수정

    • 수정 전

      - name: Deploy to Azure Web App
        id: deploy-to-webapp
        uses: azure/webapps-deploy@v2
        with:
          app-name: 'CICDTest-as'
          slot-name: 'Production'
          publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_D8DBFBB179E7449CA1D9745E0581E194 }}
          package: '*.jar'
      
    • 수정 후

      - name: Deploy to Azure Web App
        id: deploy-to-webapp
        uses: azure/webapps-deploy@v2
        with:
          app-name: 'CICDTest-as'
          slot-name: 'Production'
          publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_D8DBFBB179E7449CA1D9745E0581E194 }}
          package: '*SNAPSHOT.jar'
      

9-2. war 파일 yaml 작성

  1. Build에서 두가지 step을 수정한다.

    1. Build with Maven 삭제 후 아래 코드로 수정

      # 1. gradle buile를 위한 권한 부여
      - name: Grant execute permission for gradlew
        run: chmod +x gradlew
        working-directory: <프로젝트 폴더명>
      
      # 2. Gradle build 진행
      - name: Build with Gradle
        run : |
          cd <프로젝트 폴더명>     # 해당 디렉토리로 이동
          ./gradlew build -x test # Gradle 빌드 실행
      
      # war 배포시 war파일명을 ROOT로 수정 
       - name: Rename War
         run : mv ROOT-0.0.1-SNAPSHOT.war ROOT.war
         working-directory: <프로젝트 폴더명>/build/libs
      
      # 3. 배포할 파일의 경로를 확인
       - name: Check path
         run: ls -lR
      

      App Services에서 war파일 배포시 프로젝트 파일이 ROOT로 되어야만 App Services에서 정상적으로 인식 후 배포가 진행된다.

    2. Upload artifact for deployment job

      path부분을 artifact가 있는 위치로 수정

      • 수정 전

        path: '${{ github.workspace }}/target/*.jar'
        
      • 수정 후

        path: '${{ github.workspace }}/<프로젝트 폴더명>/build/libs/*.war' # 3.프로젝트명 변경시 수정사항
        
        path: '${{ github.workspace }}/BLACKCODE/build/libs/*.war' # 3.프로젝트 변경시 수정사항
        
      • 해당 경로 부분에서 *. 지정하게 되면 프로젝트 빌드시 배포파일의 충돌로 인해 배포오류가 발생한다.

      • plain.war와 SNAPSHOT.war파일 두가지가 생성되기 때문에 plain이 아닌 파일로 지정해서 충돌을 피해준다.

  2. deploy 단계에서 war파일의 경로 수정

    • package 변경한 파일명(ROOT.war)으로 수정해준다.

    • 수정 전

      - name: Deploy to Azure Web App
        id: deploy-to-webapp
        uses: azure/webapps-deploy@v2
        with:
          app-name: 'CICDTest-as'
          slot-name: 'Production'
          publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_D8DBFBB179E7449CA1D9745E0581E194 }}
          package: '*.jar'
      
    • 수정 후

      - name: Deploy to Azure Web App
        id: deploy-to-webapp
        uses: azure/webapps-deploy@v2
        with:
          app-name: 'CICDTest-as'
          slot-name: 'Production'
          publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_D8DBFBB179E7449CA1D9745E0581E194 }}
          package: 'ROOT.war'
      

10. 배포

yaml파일 수정 후 commit하게되면 자동적으로 Actions가 돌아가면서 workflow의 Job 순서대로 CICD가 진행된다.

  • Github Action이 성공적으로 돌아간 모습

  • 배포 후 AppService의 url로 접속시 아래 이미지처럼 나오게 되면 성공

11. 코드 수정 후 자동 CICD 테스트

  1. 테스트용도로 Html템플릿을 다운받아 적용 후 아래와 같은 간단한 Controller 코드를 작성

    @Controller
    public class IndexController {
        
        @RequestMapping("/")
        public String index() {
            return "index.html";
        }
        
    }
    
  2. 로컬에서 제대로 페이지가 뜨는지 확인

  3. 페이지 적용에 필요한 static파일과 소스코드 모두 Commit

  4. Github Actions가 정상적으로 진행되고

  5. 아래에 표시된 링크로 다시 접속한다.

12. 완료