Skip to content

#24 1) 프로메테우스 설정 타켓 맞추기 #40

#24 1) 프로메테우스 설정 타켓 맞추기

#24 1) 프로메테우스 설정 타켓 맞추기 #40

Workflow file for this run

name: CI/CD Pipeline
on:
push:
branches:
- main
- feature/24 # 임시 추가
- feature/25 # 임시 추가
workflow_dispatch: # 수동 트리거 추가
jobs:
build:
runs-on: ubuntu-latest
steps:
# 1. 코드 체크아웃 (깃헙 리포지토리의 코드를 현재 워크플로우로 가져옴)
- name: Checkout code
uses: actions/checkout@v2
# 2. JDK 17 설정 (프로젝트를 빌드하는 데 필요한 Java 17을 설정)
- name: Set up JDK 17
uses: actions/setup-java@v2
with:
java-version: '17'
distribution: 'temurin'
# 3. Gradle을 사용하여 프로젝트 빌드 (Gradle을 통해 프로젝트를 빌드하여 실행 가능한 파일을 생성)
- name: Build with Gradle
run: ./gradlew build
# 4. Docker 데몬 설정 (GitHub Actions에서 Docker 데몬 실행을 위한 설정)
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
# 5. Docker 로그인 (Docker Hub에 로그인하여 이미지를 푸시할 수 있도록 설정)
- name: Log in to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
# 6. Docker 이미지 빌드 (프로젝트를 기반으로 Docker 이미지를 생성)
- name: Build Docker image
run: |
SHORT_SHA=$(echo ${{ github.sha }} | cut -c1-7)
docker build -t zero0zone/vintage:$SHORT_SHA .
# 7. Docker 이미지를 Docker Hub에 푸시 (생성된 Docker 이미지를 Docker Hub에 푸시)
- name: Push Docker image
run: |
SHORT_SHA=$(echo ${{ github.sha }} | cut -c1-7)
echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
docker push zero0zone/vintage:$SHORT_SHA
# 8. 현재 활성화된 환경 확인 (Blue/Green 배포에서 현재 활성화된 환경을 확인)
- name: Determine active environment
id: determine-env
uses: appleboy/ssh-action@v0.1.8
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USER }}
key: ${{ secrets.EC2_SSH_KEY }}
port: 22
script: |
if sudo grep -q 'vintage-community-blue' /etc/nginx/conf.d/default.conf; then
echo "::set-output name=ACTIVE_ENV::blue"
echo "::set-output name=TARGET_ENV::green"
else
echo "::set-output name=ACTIVE_ENV::green"
echo "::set-output name=TARGET_ENV::blue"
fi
# 9. 새 버전을 타겟 환경에 배포 (Docker Compose를 사용하여 배포)
- name: Deploy with Docker Compose
uses: appleboy/ssh-action@v0.1.8
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USER }}
key: ${{ secrets.EC2_SSH_KEY }}
port: 22
script: |
SHORT_SHA=$(echo ${{ github.sha }} | cut -c1-7)
TARGET_ENV="${{ steps.determine-env.outputs.TARGET_ENV }}"
echo "Deploying to $TARGET_ENV using image $SHORT_SHA"
cd /home/ec2-user/vintage-camera-community
# 기존 타겟 컨테이너 중지 및 제거
docker-compose -f docker-compose.yml stop vintage-community-$TARGET_ENV || true
docker-compose -f docker-compose.yml rm -f vintage-community-$TARGET_ENV || true
# docker-compose.yml에서 이미지 태그 업데이트
sed -i "s|image: zero0zone/vintage:.*|image: zero0zone/vintage:$SHORT_SHA|g" docker-compose.yml
# Docker Compose로 새로운 환경 띄우기
docker-compose -f docker-compose.yml up -d --no-deps vintage-community-$TARGET_ENV
echo "Deployment to $TARGET_ENV completed"
# 10. 새로 배포된 환경의 헬스 체크 (배포된 환경이 정상적으로 동작하는지 확인)
- name: Health check for target environment
uses: appleboy/ssh-action@v0.1.8
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USER }}
key: ${{ secrets.EC2_SSH_KEY }}
port: 22
script: |
TARGET_ENV="${{ steps.determine-env.outputs.TARGET_ENV }}"
echo "Starting health check for $TARGET_ENV"
TARGET_PORT=8080
if [ "$TARGET_ENV" == "green" ]; then
TARGET_PORT=8081
fi
MAX_RETRIES=10 # 최대 재시도 횟수 설정 30횟수에서 10횟수로 줄임
RETRY_INTERVAL=10 # 재시도 간격(초) 설정
for i in $(seq 1 $MAX_RETRIES); do # 헬스 체크 시도를 반복
HTTP_STATUS=$(curl -s -o /dev/null -w '%{http_code}' http://localhost:$TARGET_PORT) # 헬스 체크 실행
if [ "$HTTP_STATUS" = "200" ]; then # HTTP 상태 코드가 200이면 성공
echo "Health check passed for $TARGET_ENV environment on port $TARGET_PORT"
exit 0
else
echo "Attempt $i: Health check failed. Retrying in $RETRY_INTERVAL seconds..." # 헬스 체크 실패 시 재시도
sleep $RETRY_INTERVAL
fi
done
echo "Health check failed after $MAX_RETRIES attempts. Aborting deployment." # 최대 재시도 횟수를 초과하면 배포 중지
cd /home/ec2-user/vintage-camera-community
docker-compose -f docker-compose.yml stop vintage-community-$TARGET_ENV # 실패한 컨테이너 중지
docker-compose -f docker-compose.yml rm -f vintage-community-$TARGET_ENV # 실패한 컨테이너 제거
docker-compose -f docker-compose.yml logs vintage-community-$TARGET_ENV # 실패한 컨테이너의 로그 출력
exit 1
# 11. 트래픽을 새 환경으로 전환 (Nginx 설정 변경으로 트래픽을 새 환경으로 전환)
- name: Switch traffic to target environment
if: success() # 이전 단계가 성공한 경우에만 실행
uses: appleboy/ssh-action@v0.1.8
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USER }}
key: ${{ secrets.EC2_SSH_KEY }}
port: 22
script: |
ACTIVE_ENV="${{ steps.determine-env.outputs.ACTIVE_ENV }}"
TARGET_ENV="${{ steps.determine-env.outputs.TARGET_ENV }}"
echo "Switching traffic from $ACTIVE_ENV to $TARGET_ENV"
sudo sed -i "s/vintage-community-$ACTIVE_ENV/vintage-community-$TARGET_ENV/" /etc/nginx/conf.d/default.conf
sudo service nginx reload
echo "Traffic switched to $TARGET_ENV"
# 12. 이전 환경(비활성 환경) 정리 (이전 활성화된 환경의 컨테이너를 중지하고 제거)
- name: Clean up inactive environment
if: success() # 이전 단계가 성공한 경우에만 실행
uses: appleboy/ssh-action@v0.1.8
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USER }}
key: ${{ secrets.EC2_SSH_KEY }}
port: 22
script: |
ACTIVE_ENV="${{ steps.determine-env.outputs.ACTIVE_ENV }}"
echo "Cleaning up $ACTIVE_ENV environment"
cd /home/ec2-user/vintage-camera-community
docker-compose -f docker-compose.yml stop vintage-community-$ACTIVE_ENV || true
docker-compose -f docker-compose.yml rm -f vintage-community-$ACTIVE_ENV || true
echo "$ACTIVE_ENV environment cleaned up"