diff --git a/.github/workflows/asap_server_cd.yml b/.github/workflows/asap_server_cd.yml new file mode 100644 index 0000000..67263a2 --- /dev/null +++ b/.github/workflows/asap_server_cd.yml @@ -0,0 +1,97 @@ +# 워크플로우의 이름 지정 +name: ASAP-Server CD + +# 해당 workflow가 언제 실행될 것인지에 대한 트리거를 지정 +on: + push: + branches: [ main ] # main branch로 push 될 때 실행됩니다. + +env: + S3_BUCKET_NAME: asap-server + +jobs: + build: + name: Code deployment + + # 실행 환경 + runs-on: ubuntu-latest + + steps: + + # 1) 워크플로우 실행 전 기본적으로 체크아웃 필요 + - name: checkout + uses: actions/checkout@v3 + + # 2) JDK 11버전 설치, 다른 JDK 버전을 사용하다면 수정 + - name: Set up JDK 11 + uses: actions/setup-java@v3 + with: + java-version: '11' + distribution: 'temurin' + + # 3) 환경변수 파일 생성 + - name: make application.properties 파일 생성 + run: | + ## create application.yml + mkdir ./src/main/resources + cd ./src/main/resources + + # application.yml 파일 생성 + touch ./application.yml + + # GitHub-Actions 에서 설정한 값을 application.yml 파일에 쓰기 + echo "${{ secrets.ASAP_APPLICATION }}" >> ./application.yml + + # application.yml 파일 확인 + cat ./application.yml + shell: bash + + # 이 워크플로우는 gradle build + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Build with Gradle # 실제 application build(-x 옵션을 통해 test는 제외) + run: ./gradlew build -x test + + # 디렉토리 생성 + - name: Make Directory + run: mkdir -p deploy + + # Jar 파일 복사 + - name: Copy Jar + run: cp ./build/libs/*.jar ./deploy + + # appspec.yml 파일 복사 + - name: Copy appspec.yml + run: cp appspec.yml ./deploy + + # script files 복사 + - name: Copy script + run: cp ./scripts/*.sh ./deploy + + - name: Make zip file + run: zip -r ./asap_server.zip ./deploy + shell: bash + + - 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_KEY }} + aws-region: ap-northeast-2 + + - name: Upload to S3 + run: aws s3 cp --region ap-northeast-2 ./asap_server.zip s3://$S3_BUCKET_NAME/ + + # Deploy + - name: Deploy + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_KEY }} + run: + aws deploy create-deployment + --application-name asap-server-codedeploy + --deployment-group-name asap-server-codedeploy-group + --file-exists-behavior OVERWRITE + --s3-location bucket=asap-server,bundleType=zip,key=asap_server.zip + --region ap-northeast-2 diff --git a/appspec.yml b/appspec.yml new file mode 100644 index 0000000..44c46f6 --- /dev/null +++ b/appspec.yml @@ -0,0 +1,19 @@ +version: 0.0 +os: linux + +files: + - source: / + destination: /home/ubuntu/app + overwrite: yes + +permissions: + - object: / + pattern: "**" + owner: ubuntu + group: ubuntu + +hooks: + AfterInstall: + - location: deploy.sh + timeout: 60 + runas: ubuntu diff --git a/scripts/deploy.sh b/scripts/deploy.sh new file mode 100644 index 0000000..c4d4d51 --- /dev/null +++ b/scripts/deploy.sh @@ -0,0 +1,82 @@ +#!/bin/bash +BUILD_PATH=$(ls /home/ubuntu/app/ASAP-Server-Lab-0.0.1-SNAPSHOT.jar) +JAR_NAME=$(basename $BUILD_PATH) +echo "> build 파일명: $JAR_NAME" + +echo "> build 파일 복사" +DEPLOY_PATH=/home/ubuntu/app/nonstop/jar/ +cp $BUILD_PATH $DEPLOY_PATH + +echo "> 현재 구동중인 Set 확인" +CURRENT_PROFILE=$(curl -s http://localhost/profile) +echo "> $CURRENT_PROFILE" + +# 쉬고 있는 set 찾기: set1이 사용중이면 set2가 쉬고 있고, 반대면 set1이 쉬고 있음 +if [ $CURRENT_PROFILE == set1 ] +then + IDLE_PROFILE=set2 + IDLE_PORT=8082 +elif [ $CURRENT_PROFILE == set2 ] +then + IDLE_PROFILE=set1 + IDLE_PORT=8081 +else + echo "> 일치하는 Profile이 없습니다. Profile: $CURRENT_PROFILE" + echo "> set1을 할당합니다. IDLE_PROFILE: set1" + IDLE_PROFILE=set1 + IDLE_PORT=8081 +fi + +echo "> application.jar 교체" +IDLE_APPLICATION=$IDLE_PROFILE-ASAP-Server-Lab.jar +IDLE_APPLICATION_PATH=$DEPLOY_PATH$IDLE_APPLICATION + +ln -Tfs $DEPLOY_PATH$JAR_NAME $IDLE_APPLICATION_PATH + +echo "> $IDLE_PROFILE 에서 구동중인 애플리케이션 pid 확인" +IDLE_PID=$(pgrep -f $IDLE_APPLICATION) + +if [ -z $IDLE_PID ] +then + echo "> 현재 구동중인 애플리케이션이 없으므로 종료하지 않습니다." +else + echo "> kill -15 $IDLE_PID" + kill -15 $IDLE_PID + sleep 5 +fif + +echo "> $IDLE_PROFILE 배포" +nohup java -jar -Duser.timezone=Asia/Seoul -Dspring.profiles.active=$IDLE_PROFILE $IDLE_APPLICATION_PATH >> /home/ubuntu/app/nohup.out 2>&1 & + +echo "> $IDLE_PROFILE 10초 후 Health check 시작" +echo "> curl -s http://localhost:$IDLE_PORT/health " +sleep 10 + +for retry_count in {1..10} +do + response=$(curl -s http://localhost:$IDLE_PORT/actuator/health) + up_count=$(echo $response | grep 'UP' | wc -l) + + if [ $up_count -ge 1 ] + then # $up_count >= 1 ("UP" 문자열이 있는지 검증) + echo "> Health check 성공" + break + else + echo "> Health check의 응답을 알 수 없거나 혹은 status가 UP이 아닙니다." + echo "> Health check: ${response}" + fi + + if [ $retry_count -eq 10 ] + then + echo "> Health check 실패. " + echo "> Nginx에 연결하지 않고 배포를 종료합니다." + exit 1 + fi + + echo "> Health check 연결 실패. 재시도..." + sleep 10 +done + +echo "> 스위칭" +sleep 10 +/home/ubuntu/app/nonstop/switch.sh diff --git a/src/main/java/com/asap/asapserverlab/controller/HelloController.java b/src/main/java/com/asap/asapserverlab/controller/HelloController.java index 791cb69..8832e40 100644 --- a/src/main/java/com/asap/asapserverlab/controller/HelloController.java +++ b/src/main/java/com/asap/asapserverlab/controller/HelloController.java @@ -7,6 +7,6 @@ public class HelloController { @GetMapping("/hello") public String getHello() { - return "Hello World"; + return "Hello World HI"; } }