본문 바로가기
프로그래밍/SpringBoot

Github Actions + AWS CI/CD (2)

by 코딩중독 2024. 3. 8.

목차

    이전 글에서 AWS 준비를 완료하고 인텔리제이와 Github에서 진행하는 내용 정리

     

    2024.03.08 - [프로그래밍/SpringBoot] - Github Actions + AWS CI/CD (1)

     

    Github Actions + AWS CI/CD (1)

    Github Actions를 사용해서 지속적 통합(CI)과 배포(CD)에 대한 내용 정리 특이점이 없다면 글보다는 이미지로... AWS IAM 사용자 생성 AWS 리소스에 대한 엑세스를 위한 보안 자격 증명을 관리하는 데 사

    story-to-me.tistory.com

     

    Github Repository 생성과 프로젝트 연결

    Github Repository 생성과 프로젝트 연결은 생략한다...

     

     

    스프링부트 프로젝트 설정

    start.sh, stop.sh

    스프링부트 애플리케이션의 중지/배포/실행을 위한 스크립트를 추가한다

    프로젝트 루트 디렉토리 하위에 scripts 폴더를 생성하고 start.sh와 stop.sh 파일을 생성한다

     

    start.sh

    # 애플리케이션 루트 경로
    PROJECT_ROOT="/home/ubuntu/app"
    
    # 실행할 jar 파일 경로
    JAR_FILE="$PROJECT_ROOT/build/libs/*SNAPSHOT.jar"
    
    # 애플리케이션의 로그를 저장할 파일 경로
    APP_LOG="$PROJECT_ROOT/application.log"
    
    # 애플리케이션의 에러 로그를 저장할 파일 경로
    ERROR_LOG="$PROJECT_ROOT/error.log"
    
    # 배포 스크립트 실행 로그를 저장할 파일 경로
    DEPLOY_LOG="$PROJECT_ROOT/deploy.log"
    
    TIME_NOW=$(date +%c)
    
    # build 파일 복사
    echo "$TIME_NOW > $JAR_FILE 파일 복사" >> $DEPLOY_LOG
    cp $PROJECT_ROOT/build/libs/*.jar $JAR_FILE
    
    # jar 파일 실행
    echo "$TIME_NOW > $JAR_FILE 파일 실행" >> $DEPLOY_LOG
    nohup java -jar $JAR_FILE > $APP_LOG 2> $ERROR_LOG &
    
    # 각 단계의 작업 내용과 실행된 프로세스 기록
    CURRENT_PID=$(pgrep -f $JAR_FILE)
    echo "$TIME_NOW > 실행된 프로세스 아이디 $CURRENT_PID 입니다." >> $DEPLOY_LOG

     

    stop.sh

    # 애플리케이션 루트 경로
    PROJECT_ROOT="/home/ubuntu/app"
    
    # 실행할 jar 파일 경로
    JAR_FILE="$PROJECT_ROOT/build/libs/*SNAPSHOT.jar"
    
    DEPLOY_LOG="$PROJECT_ROOT/deploy.log"
    
    TIME_NOW=$(date +%c)
    
    # 현재 구동 중인 애플리케이션 pid 확인
    CURRENT_PID=$(pgrep -f $JAR_FILE)
    
    # 프로세스가 켜져 있으면 종료
    if [ -z $CURRENT_PID ]; then
      echo "$TIME_NOW > 현재 실행중인 애플리케이션이 없습니다" >> $DEPLOY_LOG
    else
      echo "$TIME_NOW > 실행중인 $CURRENT_PID 애플리케이션 종료 " >> $DEPLOY_LOG
      kill -15 $CURRENT_PID
    fi

     

    deploy.sh

    자동 배포를 위한 스크립트를 추가한다

    프로젝트 루트 디렉토리 하위에 deploy.sh 파일을 생성한다

     

    deply.sh

    REPOSITORY=/home/ubuntu/app
    
    echo "> 현재 구동 중인 애플리케이션 pid 확인"
    
    CURRENT_PID=$(pgrep -fla java | grep portfolio-notice | awk '{print $1}')
    
    echo "현재 구동 중인 애플리케이션 pid: $CURRENT_PID"
    
    if [ -z "$CURRENT_PID" ]; then
      echo "현재 구동 중인 애플리케이션이 없으므로 종료하지 않습니다."
    else
      echo "> kill -15 $CURRENT_PID"
      kill -15 $CURRENT_PID
      sleep 5
    fi
    
    echo "> 새 애플리케이션 배포"
    
    JAR_NAME=$(ls -tr $REPOSITORY/*SNAPSHOT.jar | tail -n 1)
    
    echo "> JAR NAME: $JAR_NAME"
    
    echo "> $JAR_NAME 에 실행권한 추가"
    
    chmod +x $JAR_NAME
    
    echo "> $JAR_NAME 실행"
    
    nohup java -jar -Duser.timezone=Asia/Seoul $JAR_NAME >> $REPOSITORY/nohup.out 2>&1 &

     

    appspec.yml

    배포 구성 파일을 추가한다

    프로젝트 루트 디렉토리 하위에 appspec.yml 파일을 생성한다

     

    appspec.yml

    version: 0.0  # CodeDeploy 배포 구성 파일 버전
    
    os: linux  # 대상 인스턴스의 운영 체제
    
    files:
      - source: /  # 소스 디렉토리(애플리케이션 배포 파일이 있는 경로)
        destination: /home/ubuntu/app/  # 대상 디렉토리(배포 파일이 복사될 경로)
        overwrite: yes  # 대상 디렉토리에 이미 파일이 있는 경우 덮어쓸지 여부
    
    permissions:
      - object: /  # 대상 디렉토리와 그 아래의 모든 파일 및 디렉토리에 대한 권한 설정
        pattern: "**"  # 모든 파일 및 디렉토리를 대상으로 함
        owner: ubuntu  # 파일 및 디렉토리의 소유자
        group: ubuntu  # 파일 및 디렉토리의 그룹
    
    hooks:
      AfterInstall:  # 배포 후 실행되는 후크
        - location: scripts/stop.sh  # 배포 후 실행될 스크립트의 위치
          timeout: 60  # 스크립트 실행 제한 시간 (초 단위)
          runas: ubuntu  # 스크립트를 실행할 사용자
    
      ApplicationStart:  # 애플리케이션 시작 시 실행되는 후크
        - location: scripts/start.sh  # 애플리케이션 시작 후 실행될 스크립트의 위치
          timeout: 60  # 스크립트 실행 제한 시간 (초 단위)
          runas: ubuntu  # 스크립트를 실행할 사용자

     

    CICD.yml

    프로젝트 루트 디렉토리 하위에 .github/workflows/CICD.yml 파일을 생성한다

     

    CICD.yml

    name: Java+SpringBoot CI/CD with Gradle  # 이 워크플로우의 이름
    
    on:
      push:  # 코드가 push될 때
        branches: ["master"]  # master 브랜치에 대해서만 작동
      pull_request:  # Pull Request가 열렸을 때
        branches: ["master"]  # master 브랜치에 대해서만 작동
    
    env:  # 환경 변수 설정
      AWS_REGION: ap-northeast-2  # AWS 리전
      AWS_S3_BUCKET: portfolio-notice  # AWS S3 버킷 이름
      AWS_CODE_DEPLOY_APPLICATION: portfolio-notice  # AWS CodeDeploy 어플리케이션 이름
      AWS_CODE_DEPLOY_GROUP: portfolio-notice-group  # AWS CodeDeploy 배포 그룹 이름
    
    permissions:  # 권한 설정
      contents: read  # 컨텐츠에 대한 읽기 권한 설정
    
    jobs:  # 작업 정의
      build:  # 빌드 작업
    
        runs-on: ubuntu-latest  # GitHub Actions가 실행될 환경 지정
    
        steps:  # 작업 단계
          - uses: actions/checkout@v3  # 소스 코드를 체크아웃하는 단계
    
          - name: Set up JDK 17  # JDK 17 설정
            uses: actions/setup-java@v3  # Java 환경 설정 액션 사용
            with:
              java-version: '17'  # 사용할 Java 버전
              distribution: 'corretto'  # Corretto 배포판 사용
    
          - name: Add permission  # 권한 추가 단계
            run: chmod +x gradlew  # gradlew 파일에 실행 권한 추가
    
          - name: Build with Gradle  # Gradle로 빌드하는 단계
            run: ./gradlew clean --stacktrace --info build  # Gradle을 사용하여 애플리케이션을 빌드하는 스크립트 실행
            shell: bash  # 실행할 셸 지정

     

     

    여기까지 준비가 되면 Github 저장소에 push를 한다

    프로젝트와 연결된 저장소의 Actions 탭을 확인한다

    Github Actions

     

    CI 성공

     

    다음 단계는 배포를 테스트한다

    '프로그래밍 > SpringBoot' 카테고리의 다른 글

    [AWS EC2] MySQL 설치  (0) 2024.06.18
    Github Actions + AWS CI/CD (3)  (0) 2024.03.08
    Github Actions + AWS CI/CD (1)  (1) 2024.03.08