From 9ef2e845b57cf006100768594bed99c13306758e Mon Sep 17 00:00:00 2001 From: thguss Date: Thu, 17 Oct 2024 01:22:29 +0900 Subject: [PATCH] fix: updated to blue-green deploy --- .github/workflows/deploy-dev.yml | 67 +++++++++++--------- script/deploy.sh | 105 ++++++++++++++++++++++++++----- 2 files changed, 126 insertions(+), 46 deletions(-) diff --git a/.github/workflows/deploy-dev.yml b/.github/workflows/deploy-dev.yml index 2401ceae..194389c6 100644 --- a/.github/workflows/deploy-dev.yml +++ b/.github/workflows/deploy-dev.yml @@ -1,71 +1,76 @@ -name: deploy-dev +name: CD-dev on: release: - types: [ published ] + types: [ "published" ] jobs: - build: - runs-on: ubuntu-20.04 + deploy-ci: + runs-on: ubuntu-latest steps: - - name: Checkout + - name: Checkout Latest Repo uses: actions/checkout@v3 + # 최신 저장소에서 체크아웃 - name: Set up JDK 17 uses: actions/setup-java@v3 with: - java-version: 17 - distribution: 'temurin' - cache: gradle + distribution: 'corretto' + java-version: '17' + # 자바 버전을 JDK 17로 설정 - - name: Create application-secret.yml - run: | - pwd - cd ./smeem-bootstrap/src/main/resources - touch ./application-secret.yml - echo "${{ secrets.APPLICATION_SECRET_YML }}" >> ./application-secret.yml - cat ./application-secret.yml - - - name: Configure AWS credentials + - 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-access-key-id: ${{ secrets.AWS_ACCESS_KEY_DEV }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_KEY_DEV }} aws-region: ${{ secrets.AWS_REGION }} + # AWS 자격 증명 설정 - - name: Set FCM_JSON_PATH - run: echo "FCM_JSON_PATH=smeem-output-notification/src/main/resources/firebase-config/smeem_fcm_dev.json" >> $GITHUB_ENV + - name: Set FCM JSON File Path + run: | + echo "FCM_JSON_PATH=smeem-output-notification/src/main/resources/firebase-config/ \ + smeem_fcm_dev.json" >> $GITHUB_ENV + # FCM JSON 파일 위치 경로 설정 - - name: Create FireBase JSON file From AWS + - name: Create FCM JSON File from AWS run: aws s3 cp --region ap-northeast-2 ${{ secrets.AWS_S3_FCM_JSON_URI_DEV }} ${{ env.FCM_JSON_PATH }} + # FCM JSON 파일 복사 + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + shell: bash + # gradlew 파일에 실행 권한 부여 - name: Build with Gradle - run: | - chmod +x ./gradlew - ./gradlew build -x test + run: ./gradlew clean build -x test shell: bash + # 그래들로 빌드 - - name: Set docker + - name: Set Docker uses: docker/setup-buildx-action@v2.9.1 + # 도커 설정 - - name: Login docker + - name: Login Docker uses: docker/login-action@v2.2.0 with: username: ${{ secrets.DOCKERHUB_LOGIN_USERNAME_DEV }} password: ${{ secrets.DOCKERHUB_LOGIN_ACCESSTOKEN_DEV }} + # 도커에 로그인 - - name: Build docker image + - name: Docker Build run: | docker build --platform linux/amd64 -t smeemdev/smeem-dev:latest -f Dockerfile-dev . docker push smeemdev/smeem-dev:latest deploy-cd: - needs: build - runs-on: ubuntu-20.04 + needs: deploy-ci + runs-on: ubuntu-latest + # deploy-ci 이후 작업 실행 steps: - - name: SSH로 서버 접속 + - name: Connect to EC2 and Deploy uses: appleboy/ssh-action@master with: host: ${{ secrets.RELEASE_SERVER_IP_DEV }} diff --git a/script/deploy.sh b/script/deploy.sh index b6c0e495..eb75c45a 100644 --- a/script/deploy.sh +++ b/script/deploy.sh @@ -1,6 +1,9 @@ #!/bin/bash source .env +NGINX_CONFIG_PATH="/etc/nginx" +ALL_PORT=("8081" "8082") +AVAILABLE_PORT=() REGISTRY_URL=${REGISTRY_URL} IMAGE_NAME=${IMAGE_NAME} SECRET_MANAGER_TOKEN=${SECRET_MANAGER_TOKEN} @@ -9,46 +12,118 @@ TAG="latest" CONTAINER_NAME="smeem" HEALTH_CHECK_URI="/actuator/health" -echo "> Pull docker image" +docker_ps_output=$(sudo docker ps | grep $CONTAINER_NAME) +running_container_name=$(echo "$docker_ps_output" | awk '{print $NF}') +blue_port=$(echo "$running_container_name" | awk -F'-' '{print $NF}') + +if [ -z "$blue_port" ]; then + echo "> Running port: none" +else + echo "> Running port: $blue_port" +fi + +# 실행 가능한 포트 확인 +for item in "${ALL_PORT[@]}"; do + if [ "$item" != "$blue_port" ]; then + AVAILABLE_PORT+=("$item") + fi +done + +# 실행 가능한 포트 없으면 끝내기 +if [ ${#AVAILABLE_PORT[@]} -eq 0 ]; then + echo "> No available port" + exit 1 +fi + +green_port=${AVAILABLE_PORT[0]} + +echo "----------------------------------------------------------------------" + +# 도커 이미지 풀 받기 +echo "> Pull Docker Image" sudo docker pull "${REGISTRY_URL}"/"${IMAGE_NAME}":"${TAG}" -echo "> Stop running docker container" -if [ "$(sudo docker ps -a -q -f name=${CONTAINER_NAME})" ]; then - sudo docker stop ${CONTAINER_NAME} - sudo docker rm ${CONTAINER_NAME} +# 그린 포트로 서버 실행 +echo "> Run Docker with ${green_port} port" + +if [ "$(sudo docker ps -a -q -f name=${CONTAINER_NAME}-"${green_port}")" ]; then + docker stop ${CONTAINER_NAME}-"${green_port}" + docker rm ${CONTAINER_NAME}-"${green_port}" fi -echo "> Run docker" -sudo docker run -d --name ${CONTAINER_NAME} -p 80:8080 \ +docker run -d --name ${CONTAINER_NAME}-"${green_port}" -p "${green_port}":8080 \ -e SECRET_MANAGER_TOKEN="${SECRET_MANAGER_TOKEN}" \ -e SECRET_MANAGER_WORKSPACE_ID="${SECRET_MANAGER_WORKSPACE_ID}" \ "${REGISTRY_URL}"/"${IMAGE_NAME}":${TAG} echo "----------------------------------------------------------------------" +# green_port 서버 실행 확인 sleep 15 -for RETRY_COUNT in {1..15} + +for retry_count in {1..15} do echo "> Health check" - RESPONSE=$(curl -s http://localhost${HEALTH_CHECK_URI}) + response=$(curl -s http://localhost${HEALTH_CHECK_URI}) # shellcheck disable=SC2126 - UP_COUNT=$(echo "${RESPONSE}" | grep 'UP' | wc -l) + up_count=$(echo "${response}" | grep 'UP' | wc -l) - if [ "${UP_COUNT}" -ge 1 ] + if [ "${up_count}" -ge 1 ] then - echo "> Success" + echo "> SUCCESS" break else echo "> Not run yet" - echo "> 응답 결과: ${RESPONSE}" + echo "> Response: ${response}" fi - if [ "${RETRY_COUNT}" -eq 15 ] + + if [ "${retry_count}" -eq 15 ] then echo "> Failed to running server" - sudo docker rm -f ${CONTAINER_NAME} + docker rm -f ${CONTAINER_NAME}-"${green_port}" exit 1 fi + sleep 2 done + +echo "----------------------------------------------------------------------" + +# Nginx 포트 스위칭 +echo "> Nginx Switching" + +# Nginx 실행 중인지 확인 +if ! pgrep -x "nginx" > /dev/null +then + echo "Start Nginx" + sudo systemctl start nginx +fi + +## 서비스 URL 업데이트 및 Nginx 리로드 +#echo "set \$service_url http://127.0.0.1:${green_port};" | sudo tee ${NGINX_CONFIG_PATH}/conf.d/service-url.inc +#sudo nginx -t && sudo nginx -s reload + +sleep 1 + echo "----------------------------------------------------------------------" + +# Nginx 통해서 서버 접근 가능한지 확인 +response=$(curl -s http://localhost:"${green_port}"${HEALTH_CHECK_URI}) +# shellcheck disable=SC2126 +up_count=$(echo "$response" | grep 'UP' | wc -l) + +if [ "$up_count" -ge 1 ] +then + echo "> Success to Switching" +else + echo "> Failed to Switching" + echo "> Response: ${response}" + exit 1 +fi + +# blue_port 서버 있다면 중단 +if [ -n "$blue_port" ]; then + echo "> Stop ${blue_port} port" + sudo docker rm -f ${CONTAINER_NAME}-"${blue_port}" +fi