SEB_Main-Project 배포자동화

subimm_·2023년 1월 19일
0

코드스테이츠

목록 보기
81/83

메인 프로젝트 진행 중 유저 부분 구현을 끝냈다.
팀원과 깃허브액션으로 배포자동화를 진행했고 간단하게 구현 방법을 기록해두었다.

📔 GithubActions

  • 먼저 github Actions 에서 workflow를 생성(java with Gradle)
    • 자동화된 프로세스로 job으로 이루어져 이벤트에 의해서 실행된다.
    • default 브랜치에 생성된다.
  • workflow를 생성하면 만들어지는 gradle.yml 파일에 설정들을 추가
    • jobs : 워크플로우의 기본 단위 여러 작업을 병렬적으로 실행, 순차적으로 실행하도록 설정 가능
    • steps : 작업에서 커맨드를 실행하는 독립 단위. 하나의 job의 스텝들은 서로 데이터 공유

  • 깃헙 액션으로 배포자동화 하는 동작 방식은 전에 학습 시 블로깅 한 글 참고
    https://velog.io/@subimm/SEBBE-75%EC%9D%BC%EC%B0%A8-%EB%B0%B0%ED%8F%AC-%EC%9E%90%EB%8F%99%ED%99%942

📜 gradle.yml

on:
  push:
    branches: ["back"]
  • 설정한 브랜치에서 push 이벤트가 발생하면 이 workflow가 실행된다.
  • 브랜치는 back으로 설정해주었다.
env:
  S3_BUCKET_NAME: animalsquad
  RESOURCE_PATH: ./server/src/main/resources-prod/application.yml
  • 작업 내에서 환경변수 설정
jobs:
  build:

    runs-on: ubuntu-20.04

    steps:
    - uses: actions/checkout@v3
    - name: Set up JDK 11
      uses: actions/setup-java@v3
      with:
        java-version: '11'
        distribution: 'temurin'
  • ec2 환경인 ubuntu에서 실행 / 브랜치에 체크아웃 / java 설정
  • 미리 만들어진 패키징을 사용
    - name: Set yaml file
      uses: microsoft/variable-substitution@v1
      with:
        files: ${{ env.RESOURCE_PATH }}
      env:
        spring.datasource.url: jdbc:mysql://${{ secrets.ENDPOINT }}:${{ secrets.PORT }}/animalsquad?serverTimezone=Asia/Seoul
        spring.datasource.username: ${{ secrets.MYSQL_USERNAME }}
        spring.datasource.password: ${{ secrets.MYSQL_PASSWORD }}
        jwt.key: ${{ secrets.JWT_SECRET_KEY }}
        cloud.aws.credentials.access-key: ${{ secrets.S3_ACCESS_KEY }}
        cloud.aws.credentials.secret-key: ${{ secrets.S3_SECRET_KEY }}
        cloud.aws.region.static: ${{ secrets.S3_REGION }}
        cloud.aws.s3.bucket: ${{ secrets.S3_BUCKET }}
  • application.yml 파일을 세팅해준다.
  • resources-prod 의 yml 파일로 지정
  • 각 값들은 github secrets에 저장해서 사용

🔍 resources 폴더 아래에 두고 빌드를 하면 속한 파일 전부가 jar에 포함이 된다.
profile을 구분하지 않고 빌드할 경우 jar에는 모든 profile의 설정이 담기게 되어 분리가 필요

  • application.yml 파일을 dev / prod 로 나누었고 환경변수로 설정되어 있던 것들을 github secrets를 사용하여 빌드 시에 yml 파일을 구성하게 했다.
  • secrets로 값을 넣어주면 application.yml 파일에 있는 값이 무엇이든 덮어쓰게 된다.
    • 아무 값이나 넣어줘도 sercrets 값으로 불러온다.
  • 그래서 환경변수로 쓰던 yml 파일 값을 아래와 같은 형식 그대로 두었다.(로컬에서 테스트 시 환경변수로 불러와 사용하기 위함)
  • build.gradle에 profle 설정해주어야 함.
    ext.profile = (!project.hasProperty('profile') || !profile) ? "dev" : profile
    sourceSets {
    	main {
    		resources {
    			srcDirs "src/main/resources", "src/main/resources-${profile}"
    		}
    	}
  • 지정해주지 않으면 default 값은 dev로 실행된다.

    - name: Add permission
      run: chmod +x ./server/gradlew
      shell: bash
  • 권한 부여
    - name: Build with Gradle
      run: cd server; ./gradlew build -Pprofile=prod
      shell: bash
  • 프로젝트 빌드 -Pprofile=prod 설정을 붙여주어야 prod의 yml로 지정이 된다.
      # build한 후 프로젝트를 압축
    - name: Make zip file
      run: zip -r ./animalsquad-deploy.zip .
      shell: bash
      working-directory: ./server
  • 빌드 후 압축 파일로 만든다.
      # Access Key와 Secret Access Key를 통해 권한을 확인
    - name: Configure AWS credentials
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        aws-region: ap-northeast-2

      # 압축한 프로젝트를 S3로 전송
    - name: Upload to S3
      run: aws s3 cp --region ap-northeast-2 ./animalsquad-deploy.zip s3://$S3_BUCKET_NAME/animalsquad-deploy.zip
      working-directory: ./server
  • secrets에 등록해 둔 AWS 키를 가지고 권한을 확인한 뒤 압축한 파일을 S3로 전송한다.
  • S3_BUCKET_NAME 은 맨 위 env 부분에서 설정해 둔 값
      # CodeDeploy에게 배포 명령
    - name: Code Deploy
      run: >
        aws deploy create-deployment --application-name animalsquad
        --deployment-config-name CodeDeployDefault.AllAtOnce
        --deployment-group-name animalsquad-group
        --s3-location bucket=$S3_BUCKET_NAME,bundleType=zip,key=animalsquad-deploy.zip
  • Code Deploy에게 배포 명령을 전송한다. (Code Deploy 애플리케이션 생성 후 배포그룹 생성해주기)

📔 appspec.yml (루트 디렉토리에 생성)

version: 0.0
os: linux
files:
  - source:  /
    destination: /home/ubuntu/action
    overwrite: yes

permissions:
  - object: /
    pattern: "**"
    owner: ubuntu
    group: ubuntu

hooks:
  ApplicationStart:
    - location: scripts/deploy.sh
      timeout: 60
      runas: ubuntu
  • destination : 배포가 진행될 디렉토리
  • location : 최상위 scripts폴더 내 deploy.sh 스크립트가 실행된다.

📔 deploy.sh ( 루트 디렉토리에 scripts 폴더 생성 후 파일 생성 )

#!/bin/bash
# 빌드 파일 .jar 파일 이름을 수정
BUILD_JAR=$(ls /home/ubuntu/action/build/libs/server-0.0.1-SNAPSHOT.jar)
JAR_NAME=$(basename $BUILD_JAR)

echo "> 현재 시간: $(date)" >> /home/ubuntu/action/deploy.log

echo "> build 파일명: $JAR_NAME" >> /home/ubuntu/action/deploy.log

echo "> build 파일 복사" >> /home/ubuntu/action/deploy.log
DEPLOY_PATH=/home/ubuntu/action/
cp $BUILD_JAR $DEPLOY_PATH

echo "> 현재 실행중인 애플리케이션 pid 확인" >> /home/ubuntu/action/deploy.log
CURRENT_PID=$(pgrep -f $JAR_NAME)

if [ -z $CURRENT_PID ]
then
  echo "> 현재 구동중인 애플리케이션이 없으므로 종료하지 않습니다." >> /home/ubuntu/action/deploy.log
else
  echo "> kill -9 $CURRENT_PID" >> /home/ubuntu/action/deploy.log
  sudo kill -9 $CURRENT_PID
  sleep 5
fi


DEPLOY_JAR=$DEPLOY_PATH$JAR_NAME
echo "> DEPLOY_JAR 배포"    >> /home/ubuntu/action/deploy.log
sudo nohup java -jar $DEPLOY_JAR --spring.profiles.active=prod >> /home/ubuntu/deploy.log 2>/home/ubuntu/action/deploy_err.log &
echo >> /home/ubuntu/action/deploy.log
  • 배포 진행 상황 로그 기록하고 배포된 빌드 파일 실행
profile
코린이의 공부 일지

0개의 댓글