diff --git a/.github/workflows/kok-prod-CD.yml b/.github/workflows/kok-prod-CD.yml index 1cb2df4f..59ab5bb2 100644 --- a/.github/workflows/kok-prod-CD.yml +++ b/.github/workflows/kok-prod-CD.yml @@ -17,90 +17,24 @@ jobs: echo "LATEST_TAG=$LATEST_TAG" >> $GITHUB_ENV - name: Create SSH key file - run: echo "${{ secrets.NCP_KEY }}" > /tmp/NCP_KEY.pem + run: echo "${{ secrets.AWS_KEY }}" > /tmp/AWS_KEY.pem - name: Set permissions for SSH key file - run: chmod 600 /tmp/NCP_KEY.pem + run: chmod 600 /tmp/AWS_KEY.pem - - name: Upload Compose files & nginx.conf to NCP + - name: Upload Compose files & deploy.sh to AWS run: | - scp -i /tmp/NCP_KEY.pem -o StrictHostKeyChecking=no infra/docker-compose-blue.yml ${{ secrets.NCP_USER }}@${{ secrets.NCP_PROD_HOST }}:${{ secrets.COMPOSE_FILE_PATH }} - scp -i /tmp/NCP_KEY.pem -o StrictHostKeyChecking=no infra/docker-compose-green.yml ${{ secrets.NCP_USER }}@${{ secrets.NCP_PROD_HOST }}:${{ secrets.COMPOSE_FILE_PATH }} - scp -i /tmp/NCP_KEY.pem -o StrictHostKeyChecking=no infra/docker-compose-env.yml ${{ secrets.NCP_USER }}@${{ secrets.NCP_PROD_HOST }}:${{ secrets.COMPOSE_FILE_PATH }} - scp -i /tmp/NCP_KEY.pem -o StrictHostKeyChecking=no infra/docker-compose-nginx.yml ${{ secrets.NCP_USER }}@${{ secrets.NCP_PROD_HOST }}:${{ secrets.COMPOSE_FILE_PATH }} + scp -i /tmp/AWS_KEY.pem -o StrictHostKeyChecking=no infra/docker-compose-blue.yml ${{ secrets.AWS_USER }}@${{ secrets.AWS_PROD_HOST }}:${{ secrets.COMPOSE_FILE_PATH }} + scp -i /tmp/AWS_KEY.pem -o StrictHostKeyChecking=no infra/docker-compose-green.yml ${{ secrets.AWS_USER }}@${{ secrets.AWS_PROD_HOST }}:${{ secrets.COMPOSE_FILE_PATH }} + scp -i /tmp/AWS_KEY.pem -o StrictHostKeyChecking=no infra/deploy.sh ${{ secrets.AWS_USER }}@${{ secrets.AWS_PROD_HOST }}:${{ secrets.COMPOSE_FILE_PATH }} - - name: Deploy to NCP (Blue-Green Auto + DB/Redis Check) + - name: Deploy to AWS via deploy.sh uses: appleboy/ssh-action@v1.0.3 with: - host: ${{ secrets.NCP_PROD_HOST }} - username: ${{ secrets.NCP_USER }} - key: ${{ secrets.NCP_KEY }} + host: ${{ secrets.AWS_PROD_HOST }} + username: ${{ secrets.AWS_USER }} + key: ${{ secrets.AWS_KEY }} script: | cd ${{ secrets.COMPOSE_FILE_PATH }} - - # .env에 최신 태그 기록 - sed -i '/^KOK_PROD_TAG=/d' .env || true - echo "KOK_PROD_TAG=${{ env.LATEST_TAG }}" >> .env - - echo "🔍 nginx 컨테이너 상태 확인..." - if ! docker compose -f docker-compose-nginx.yml ps | grep -q "Up"; then - echo "🚀 nginx 시작" - docker compose -f docker-compose-nginx.yml up -d - else - echo "✅ nginx 이미 실행 중" - fi - - - echo "🔍 ENV 컨테이너 상태 확인..." - if ! docker compose -f docker-compose-env.yml ps | grep -q "Up"; then - echo "🚀 ENV 시작" - docker compose -f docker-compose-env.yml up -d - else - echo "✅ ENV 이미 실행 중" - fi - - # 현재 사용 중인 Blue/Green 확인 - CURRENT_ENV=$(grep -o 'proxy_pass http://kok-[a-z]\+' nginx.conf | awk -F/ '{print $3}') - echo "현재 사용 중인 환경: $CURRENT_ENV" - - if [[ "$CURRENT_ENV" == "kok-blue" ]]; then - NEW_ENV="kok-green" - OLD_ENV="kok-blue" - COMPOSE_FILE="docker-compose-green.yml" - NEW_PORT=8082 - else - NEW_ENV="kok-blue" - OLD_ENV="kok-green" - COMPOSE_FILE="docker-compose-blue.yml" - NEW_PORT=8081 - fi - - echo "새로운 환경으로 배포: $NEW_ENV" - - # 새 환경 배포 - docker compose -f $COMPOSE_FILE pull - docker compose -f $COMPOSE_FILE up -d - - echo "🩺 Health Check (60초 대기)" - sleep 60 - HEALTH=$(curl -s https://prod-api.kokokok.com/v1/api/health) - echo "Health Check 결과: $HEALTH" - CODE=$(echo "$HEALTH" | jq -r '.code') - DATA=$(echo "$HEALTH" | jq -r '.data') - - if [[ "$CODE" != "200" || "$DATA" != "OK" ]]; then - echo "❌ Health Check 실패 (code: $CODE, data: $DATA), 롤백!" - docker compose -f $COMPOSE_FILE stop $NEW_ENV - docker compose -f $COMPOSE_FILE rm -f $NEW_ENV - exit 1 - fi - - echo "⚙️ nginx.conf 트래픽을 $NEW_ENV로 변경" - sed -i "s|proxy_pass http://$OLD_ENV:8080;|proxy_pass http://$NEW_ENV:8080;|" nginx.conf - - echo "🔄 Nginx 설정 reload" - docker restart kok-nginx - - echo "🧹 이전 환경($OLD_ENV) 정리" - docker compose -f docker-compose-${OLD_ENV#kok-}.yml stop $OLD_ENV - docker compose -f docker-compose-${OLD_ENV#kok-}.yml rm -f $OLD_ENV \ No newline at end of file + chmod +x deploy.sh + ./deploy.sh "${{ env.LATEST_TAG }}" diff --git a/infra/deploy.sh b/infra/deploy.sh new file mode 100644 index 00000000..feb1907d --- /dev/null +++ b/infra/deploy.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +LATEST_TAG=$1 + +# .env 최신 태그 업데이트 +sed -i '/^KOK_PROD_TAG=/d' .env || true +echo "KOK_PROD_TAG=$LATEST_TAG" >> .env + +# 현재 사용 중인 Blue/Green 확인 +CURRENT_PORT=$(grep -o 'localhost:[0-9]\+' /etc/nginx/conf.d/service-url.inc | awk -F: '{print $2}') + +if [ "$CURRENT_PORT" == "8081" ]; then + CURRENT_ENV="kok-blue" + NEW_ENV="kok-green" + NEW_PORT=8082 + COMPOSE_FILE="docker-compose-green.yml" + NEW_SERVICE_URL_PATH="/etc/nginx/conf.d/service-url-green.inc" +elif [ "$CURRENT_PORT" == "8082" ]; then + CURRENT_ENV="kok-green" + NEW_ENV="kok-blue" + NEW_PORT=8081 + COMPOSE_FILE="docker-compose-blue.yml" + NEW_SERVICE_URL_PATH="/etc/nginx/conf.d/service-url-blue.inc" +else + echo "❌ 현재 service-url.inc에 알 수 없는 포트값이 있습니다: $CURRENT_PORT" + exit 1 +fi + +echo "현재 환경: $CURRENT_ENV → 새 환경: $NEW_ENV" + +# 새 환경 배포 +docker compose -f $COMPOSE_FILE pull +docker compose -f $COMPOSE_FILE up -d + +echo "🩺 Health Check (60초 대기)" +sleep 60 +HEALTH=$(curl -s https://prod-api.kokokok.com/v1/api/health) +echo "Health Check 결과: $HEALTH" +CODE=$(echo "$HEALTH" | jq -r '.code') +DATA=$(echo "$HEALTH" | jq -r '.data') + +if [[ "$CODE" != "200" || "$DATA" != "OK" ]]; then + echo "❌ Health Check 실패 (code: $CODE, data: $DATA), 롤백!" + docker compose -f $COMPOSE_FILE stop $NEW_ENV + docker compose -f $COMPOSE_FILE rm -f $NEW_ENV + exit 1 +fi + +echo "⚙️ service-url.inc 교체: $NEW_SERVICE_URL_PATH → /etc/nginx/conf.d/service-url.inc" +sudo cp $NEW_SERVICE_URL_PATH /etc/nginx/conf.d/service-url.inc + +echo "🔄 Nginx 설정 reload" +sudo nginx -t && sudo systemctl reload nginx + +echo "🧹 이전 환경($CURRENT_ENV) 정리" +docker compose -f docker-compose-${CURRENT_ENV#kok-}.yml stop $CURRENT_ENV +docker compose -f docker-compose-${CURRENT_ENV#kok-}.yml rm -f $CURRENT_ENV diff --git a/kok-api/src/main/java/com/kok/kokapi/room/application/service/RandomProfileService.java b/kok-api/src/main/java/com/kok/kokapi/room/application/service/RandomProfileService.java index 1fd2142b..03b5a2d6 100644 --- a/kok-api/src/main/java/com/kok/kokapi/room/application/service/RandomProfileService.java +++ b/kok-api/src/main/java/com/kok/kokapi/room/application/service/RandomProfileService.java @@ -12,7 +12,7 @@ @RequiredArgsConstructor public class RandomProfileService implements CreateRandomProfileUseCase { - @Value("${ncp.object-storage-url}") + @Value("${aws.object-storage-url}") private String objectStorageUrl; private static final List ADJECTIVES = List.of( diff --git a/kok-api/src/main/resources/application-dev.yml b/kok-api/src/main/resources/application-dev.yml index cfb0d5b3..d872fa53 100644 --- a/kok-api/src/main/resources/application-dev.yml +++ b/kok-api/src/main/resources/application-dev.yml @@ -41,7 +41,7 @@ station: start-idx: 1 end-idx: 1000 -ncp: +aws: object-storage-url: ${OBJECT_STORAGE_URL} google: places: diff --git a/kok-api/src/main/resources/application-prod.yml b/kok-api/src/main/resources/application-prod.yml index 6b597d4c..16bb00e4 100644 --- a/kok-api/src/main/resources/application-prod.yml +++ b/kok-api/src/main/resources/application-prod.yml @@ -44,8 +44,9 @@ springdoc: default-consumes-media-type: application/json;charset=UTF-8 default-produces-media-type: application/json;charset=UTF-8 swagger-ui: - enabled: true + enabled: false path: /swagger + # open-api: http://data.seoul.go.kr/dataList/OA-21232/S/1/datasetView.do station: base-url: http://openapi.seoul.go.kr:8088 @@ -55,7 +56,7 @@ station: start-idx: 1 end-idx: 1000 -ncp: +aws: object-storage-url: ${OBJECT_STORAGE_URL} google: places: