GitHub Actions를 활용한 CI/CD(feat. Spring Boot + EC2)

김기현·2025년 5월 19일
0

간단하게 GitHub Actions가 뭔지 알아보고 실습을 진행해보겠습니다.

깃허브 액션(GitHub Actions)

GitHub Actions는 빌드, 테스트 및 배포 파이프라인을 자동화할 수 있는 지속적 통합 및 지속적 배포(CI/CD) 플랫폼입니다.

깃허브 액션의 구성 요소

1. Workflow

  • .github/workflows/ 디렉터리에 저장되는 YAML 파일에서 정의됨
  • 하나 이상의 Job으로 구성됨
  • 트리거 조건(on:)에 따라 자동 실행됨

2. Event

  • 워크플로 실행을 트리거하는 GitHub 상의 동작

3. Job

  • 동일한 runner(실행 환경)에서 실행되는 워크플로의 단계 집합
  • 각 Job은 별도의 runner에서 실행됨

4. Action

  • 자주 사용하는 작업을 재사용 가능하게 만든 모듈형 코드

5. Runner

  • Job을 실행할 수 있는 가상 머신 or 자체 호스팅 서버

https://docs.github.com/en/actions/about-github-actions/understanding-github-actions

CI 구축


깃허브 레포지토리를 보시면 Actions라는 탭이 있습니다. 이걸 클릭하면 위 사진과 비슷하게 나올 텐데 저는 Java with Gradle을 활용하였습니다. 레포지토리의 코드를 분석해 추천해주는 템플릿 같은 것입니다. 셀프로 설정하셔도 됩니다.

name: Java CI with Gradle

# 워크 플로우 실행 조건 설정
on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

# 작업
jobs:
  build:

    # 작업 환경
    runs-on: ubuntu-latest
    permissions:
      contents: read  # 코드 읽기 권한만 부여

    steps:
    - uses: actions/checkout@v4
    - name: Set up JDK 17
      uses: actions/setup-java@v4
      with:
        java-version: '17'
        distribution: 'temurin'

    - name: application.yml 생성 후 secret 값 복붙
      run: |  # 보안 설정된 application.yml 파일 생성
        mkdir -p ./src/main/resources
        touch ./src/main/resources/application.yml
        echo "${{ secrets.APPLICATION }}" > ./src/main/resources/application.yml
        cat ./src/main/resources/application.yml

    - name: Setup Gradle
      uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0

    - name: Build with Gradle Wrapper
      run: ./gradlew build

    - name: Upload build artifact
      uses: actions/upload-artifact@v4
      with:
        name: memo-study
        path: build/libs/memo-study-0.0.1-SNAPSHOT.jar

Github Actions에는 secret 값을 설정할 수 있는 기능이 있는데 깃허브 레포지토리의 Setting를 보시면 왼쪽에 Security에 Secrets and variables가 보일 겁니다. 저는 이렇게 빌드에 필요한 application.yml을 APPLICATION을 생성하여 넣어줬습니다.

applicaion.yml은 설정 파일이므로 프로젝트 빌드 전에 가져와야 합니다!!

CD 구축

1. AWS EC2 설정

2. EC2 접속용 SSH 키 준비
키 페어 읽는 방법
저는 텍스트 편집기로 열어서 secrets에 복사 붙여넣기 했습니다.
vscode로 열어도 되고 터미널 열어서 cat 명령어로 확인하셔도 됩니다.

3. GitHub Secrets 설정

  • EC2_HOST에는 EC2 퍼블릭 IP을 넣어줍니다.(도메인도 가능)
  • EC2_USERNAME에는 사용자명 지정(일반적으로 ubuntu)
  • EC2_SSH_KEY에는 .pem 파일 내용을 그대로 붙여넣으면 됩니다.

4. GitHub Actions Workflow 설정(전체)


name: Spring Boot CI/CD on EC2

# 워크 플로우 실행 조건 설정
on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

# 작업
jobs:
  build:

    # 작업 환경
    runs-on: ubuntu-latest
    permissions:
      contents: read  # 코드 읽기 권한만 부여

    steps:
    - uses: actions/checkout@v4
    - name: Set up JDK 17
      uses: actions/setup-java@v4
      with:
        java-version: '17'
        distribution: 'temurin'

    - name: application.yml 생성 후 secret 값 복붙
      run: |  # 보안 설정된 application.yml 파일 생성
        mkdir -p ./src/main/resources
        touch ./src/main/resources/application.yml
        echo "${{ secrets.APPLICATION }}" > ./src/main/resources/application.yml
        cat ./src/main/resources/application.yml

    - name: Setup Gradle
      uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0

    - name: Build with Gradle Wrapper
      run: ./gradlew build

    - name: Upload build artifact
      uses: actions/upload-artifact@v4
      with:
        name: memo-study
        path: build/libs/memo-study-0.0.1-SNAPSHOT.jar

  # EC2 서버로 배포 작업 정의
  deploy:
    needs: build
    runs-on: ubuntu-latest

    steps:
      - name: Download build artifact
        uses: actions/download-artifact@v4
        with:
          name: memo-study
          path: build/libs/

      # EC2에 배포
      - name: Deploy to EC2
        run: |
          # EC2 접근을 위한 SSH 개인 키 저장 및 권한 설정
          echo "${{ secrets.EC2_SSH_KEY }}" > private_key.pem
          chmod 600 private_key.pem
          
          # EC2로 JAR 파일 복사
          scp -i private_key.pem -o StrictHostKeyChecking=no build/libs/memo-study-0.0.1-SNAPSHOT.jar ${{ secrets.EC2_USERNAME }}@${{ secrets.EC2_HOST }}:/home/${{ secrets.EC2_USERNAME }}/memo-study.jar
          
          # EC2에서 기존 Java 프로세스 종료 후 새 애플리케이션 실행
          ssh -i private_key.pem -o StrictHostKeyChecking=no ${{ secrets.EC2_USERNAME }}@${{ secrets.EC2_HOST }} "pgrep java | xargs kill -9; nohup java -jar /home/${{ secrets.EC2_USERNAME }}/memo-study.jar > app.log 2>&1 &"
          
          # 보안상 개인 키 삭제
          rm -f private_key.pem



  dependency-submission:

    runs-on: ubuntu-latest
    permissions:
      contents: write

    steps:
    - uses: actions/checkout@v4
    - name: Set up JDK 17
      uses: actions/setup-java@v4
      with:
        java-version: '17'
        distribution: 'temurin'


    - name: Generate and submit dependency graph
      uses: gradle/actions/dependency-submission@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0

과정을 모두 마치면 git push를 통해 테스트해보면 됩니다.

AWS 인바운드 규칙 설정에서 Spring Boot 8080번 포트 설정(TCP 프로토콜) 하시길 ㅠ 저는 이걸 까먹고 왜 자꾸 접속이 안 되지 하고 있었습니다..

0개의 댓글