From 24e9e369b29a1aee435b2444108984d59b211a94 Mon Sep 17 00:00:00 2001 From: Johngreen Date: Sun, 28 Dec 2025 18:24:50 +0900 Subject: [PATCH] Update deploy.yml --- .gitea/workflows/deploy.yml | 238 ++++++++---------------------------- 1 file changed, 50 insertions(+), 188 deletions(-) diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index ec48126e..e5c8d001 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -1,19 +1,16 @@ -# Gitea Actions Workflow - vexplor 자동 배포 +# Gitea Actions Workflow - vexplor 이미지 빌드 & Harbor Push # -# 환경 변수: -# - GITEA_DOMAIN: g.wace.me -# - HARBOR_REGISTRY: harbor.wace.me -# - K8S_NAMESPACE: vexplor +# 동작 방식: +# 1. main 브랜치에 push 시 자동 실행 +# 2. Docker 이미지 빌드 (Backend, Frontend) +# 3. Harbor 레지스트리에 Push +# 4. 공장 서버의 Watchtower가 새 이미지 감지 후 자동 업데이트 # # 필수 Secrets (Repository Settings > Secrets): # - HARBOR_USERNAME: Harbor 사용자명 # - HARBOR_PASSWORD: Harbor 비밀번호 -# - K8S_SSH_KEY: base64로 인코딩된 SSH 비밀키 (쿠버네티스 서버 접속용) -# -# Application Secrets: -# - k8s/vexplor-secret.yaml 파일에서 관리 -name: Deploy vexplor +name: Build and Push Images on: push: @@ -24,44 +21,35 @@ on: - "backend-node/**" - "frontend/**" - "docker/**" - - "k8s/**" - ".gitea/workflows/deploy.yml" - workflow_dispatch: + paths-ignore: + - "**.md" + - "deploy/**" + - "k8s/**" + workflow_dispatch: # 수동 실행도 가능 env: GITEA_DOMAIN: g.wace.me HARBOR_REGISTRY: localhost:5001 - HARBOR_REGISTRY_K8S: harbor.wace.me HARBOR_REGISTRY_EXTERNAL: harbor.wace.me HARBOR_PROJECT: speefox_vexplor - K8S_NAMESPACE: vexplor - - # 쿠버네티스 서버 SSH 접속 정보 - K8S_SSH_HOST: 112.168.212.142 - K8S_SSH_PORT: 22 - K8S_SSH_USER: wace # Frontend 빌드 환경 변수 NEXT_PUBLIC_API_URL: "https://api.vexplor.com/api" NEXT_PUBLIC_ENV: "production" - INTERNAL_API_URL: "http://vexplor-backend-service:3001" # Frontend 설정 FRONTEND_IMAGE_NAME: vexplor-frontend - FRONTEND_DEPLOYMENT_NAME: vexplor-frontend - FRONTEND_CONTAINER_NAME: vexplor-frontend FRONTEND_BUILD_CONTEXT: frontend FRONTEND_DOCKERFILE_PATH: docker/deploy/frontend.Dockerfile # Backend 설정 BACKEND_IMAGE_NAME: vexplor-backend - BACKEND_DEPLOYMENT_NAME: vexplor-backend - BACKEND_CONTAINER_NAME: vexplor-backend BACKEND_BUILD_CONTEXT: backend-node BACKEND_DOCKERFILE_PATH: docker/deploy/backend.Dockerfile jobs: - build-and-deploy: + build-and-push: runs-on: ubuntu-24.04 steps: @@ -79,7 +67,7 @@ jobs: run: | echo "필수 도구 설치 중..." apt-get update -qq - apt-get install -y git curl ca-certificates gnupg openssh-client + apt-get install -y git curl ca-certificates gnupg # Docker 클라이언트 설치 install -m 0755 -d /etc/apt/keyrings @@ -94,7 +82,6 @@ jobs: echo "설치 완료:" git --version - ssh -V docker --version export DOCKER_HOST=unix:///var/run/docker.sock @@ -120,13 +107,13 @@ jobs: # Frontend 이미지 echo "FRONTEND_FULL_IMAGE=${HARBOR_REGISTRY}/${HARBOR_PROJECT}/${FRONTEND_IMAGE_NAME}" >> $GITHUB_ENV - echo "FRONTEND_FULL_IMAGE_K8S=${HARBOR_REGISTRY_K8S}/${HARBOR_PROJECT}/${FRONTEND_IMAGE_NAME}" >> $GITHUB_ENV # Backend 이미지 echo "BACKEND_FULL_IMAGE=${HARBOR_REGISTRY}/${HARBOR_PROJECT}/${BACKEND_IMAGE_NAME}" >> $GITHUB_ENV - echo "BACKEND_FULL_IMAGE_K8S=${HARBOR_REGISTRY_K8S}/${HARBOR_PROJECT}/${BACKEND_IMAGE_NAME}" >> $GITHUB_ENV + echo "==========================================" echo "빌드 태그: ${IMAGE_TAG}" + echo "==========================================" # Harbor 로그인 - name: Login to Harbor @@ -144,7 +131,9 @@ jobs: # Backend 빌드 및 푸시 - name: Build and Push Backend image run: | - echo "Backend 이미지 빌드 및 푸시..." + echo "==========================================" + echo "Backend 이미지 빌드 시작..." + echo "==========================================" export DOCKER_HOST=unix:///var/run/docker.sock cd /workspace/source @@ -154,14 +143,22 @@ jobs: -f ${BACKEND_DOCKERFILE_PATH} \ ${BACKEND_BUILD_CONTEXT} + echo "Backend 이미지 푸시..." docker push ${BACKEND_FULL_IMAGE}:${IMAGE_TAG} docker push ${BACKEND_FULL_IMAGE}:latest - echo "Backend 푸시 완료" + + echo "==========================================" + echo "Backend 푸시 완료!" + echo " - ${BACKEND_FULL_IMAGE}:${IMAGE_TAG}" + echo " - ${BACKEND_FULL_IMAGE}:latest" + echo "==========================================" # Frontend 빌드 및 푸시 - name: Build and Push Frontend image run: | - echo "Frontend 이미지 빌드 및 푸시..." + echo "==========================================" + echo "Frontend 이미지 빌드 시작..." + echo "==========================================" export DOCKER_HOST=unix:///var/run/docker.sock cd /workspace/source @@ -176,175 +173,40 @@ jobs: --build-arg NEXT_PUBLIC_API_URL="${NEXT_PUBLIC_API_URL}" \ ${FRONTEND_BUILD_CONTEXT} + echo "Frontend 이미지 푸시..." docker push ${FRONTEND_FULL_IMAGE}:${IMAGE_TAG} docker push ${FRONTEND_FULL_IMAGE}:latest - echo "Frontend 푸시 완료" + + echo "==========================================" + echo "Frontend 푸시 완료!" + echo " - ${FRONTEND_FULL_IMAGE}:${IMAGE_TAG}" + echo " - ${FRONTEND_FULL_IMAGE}:latest" + echo "==========================================" - # SSH 키 설정 (쿠버네티스 서버 접속용) - - name: Setup SSH Key - env: - SSH_KEY_CONTENT: ${{ secrets.K8S_SSH_KEY }} - run: | - echo "SSH 키 설정..." - - if [ -z "${SSH_KEY_CONTENT}" ]; then - echo "K8S_SSH_KEY secret이 설정되지 않았습니다!" - exit 1 - fi - - mkdir -p ~/.ssh - echo "${SSH_KEY_CONTENT}" | base64 -d > ~/.ssh/id_rsa - chmod 600 ~/.ssh/id_rsa - - # known_hosts에 쿠버네티스 서버 추가 - ssh-keyscan -p ${K8S_SSH_PORT} ${K8S_SSH_HOST} >> ~/.ssh/known_hosts 2>/dev/null - - # SSH 연결 테스트 - echo "SSH 연결 테스트..." - ssh -o StrictHostKeyChecking=no -p ${K8S_SSH_PORT} ${K8S_SSH_USER}@${K8S_SSH_HOST} "echo 'SSH 연결 성공'" - echo "SSH 키 설정 완료" - - # k8s 매니페스트 파일을 쿠버네티스 서버로 전송 - - name: Transfer k8s manifests - run: | - echo "k8s 매니페스트 파일 전송..." - cd /workspace/source - - # 쿠버네티스 서버에 디렉토리 생성 - ssh -p ${K8S_SSH_PORT} ${K8S_SSH_USER}@${K8S_SSH_HOST} "mkdir -p ~/vexplor-deploy/k8s" - - # k8s 파일 전송 - scp -P ${K8S_SSH_PORT} -r k8s/* ${K8S_SSH_USER}@${K8S_SSH_HOST}:~/vexplor-deploy/k8s/ - - echo "매니페스트 파일 전송 완료" - - # Kubernetes 배포 (SSH를 통해 원격 실행) - - name: Deploy to Kubernetes - env: - HARBOR_USER: ${{ secrets.HARBOR_USERNAME }} - HARBOR_PASS: ${{ secrets.HARBOR_PASSWORD }} - run: | - echo "Kubernetes 배포 시작 (SSH 원격 실행)..." - - # SSH를 통해 쿠버네티스 서버에서 kubectl 명령 실행 - ssh -p ${K8S_SSH_PORT} ${K8S_SSH_USER}@${K8S_SSH_HOST} << 'DEPLOY_SCRIPT' - set -e - cd ~/vexplor-deploy - - echo "네임스페이스 확인..." - kubectl apply -f k8s/namespace.yaml - - echo "ConfigMap 적용..." - kubectl apply -f k8s/vexplor-config.yaml -n vexplor - - # Secret 적용 (존재하는 경우에만) - if [ -f k8s/vexplor-secret.yaml ]; then - echo "Secret 적용..." - kubectl apply -f k8s/vexplor-secret.yaml -n vexplor - fi - - echo "네임스페이스 및 ConfigMap 적용 완료" - DEPLOY_SCRIPT - - # Harbor Registry Secret 생성 (별도로 처리 - 환경변수 사용) - echo "Harbor Registry Secret 확인..." - ssh -p ${K8S_SSH_PORT} ${K8S_SSH_USER}@${K8S_SSH_HOST} "kubectl get secret harbor-registry -n vexplor" > /dev/null 2>&1 || \ - ssh -p ${K8S_SSH_PORT} ${K8S_SSH_USER}@${K8S_SSH_HOST} "kubectl create secret docker-registry harbor-registry \ - --docker-server=${HARBOR_REGISTRY_K8S} \ - --docker-username=${HARBOR_USER} \ - --docker-password='${HARBOR_PASS}' \ - -n vexplor" - echo "Harbor Registry Secret 확인 완료" - - # Backend 배포 - echo "Backend 배포..." - ssh -p ${K8S_SSH_PORT} ${K8S_SSH_USER}@${K8S_SSH_HOST} << BACKEND_DEPLOY - set -e - cd ~/vexplor-deploy - kubectl apply -f k8s/vexplor-backend-deployment.yaml -n vexplor - - echo "Backend 이미지 업데이트..." - kubectl set image deployment/${BACKEND_DEPLOYMENT_NAME} \ - ${BACKEND_CONTAINER_NAME}=${HARBOR_REGISTRY_K8S}/${HARBOR_PROJECT}/${BACKEND_IMAGE_NAME}:latest \ - -n vexplor || true - kubectl rollout restart deployment/${BACKEND_DEPLOYMENT_NAME} -n vexplor - - echo "Backend Rolling Update 진행 중..." - kubectl rollout status deployment/${BACKEND_DEPLOYMENT_NAME} -n vexplor --timeout=5m - echo "Backend 배포 완료" - BACKEND_DEPLOY - - # Frontend 배포 - echo "Frontend 배포..." - ssh -p ${K8S_SSH_PORT} ${K8S_SSH_USER}@${K8S_SSH_HOST} << FRONTEND_DEPLOY - set -e - cd ~/vexplor-deploy - kubectl apply -f k8s/vexplor-frontend-deployment.yaml -n vexplor - - echo "Frontend 이미지 업데이트..." - kubectl set image deployment/${FRONTEND_DEPLOYMENT_NAME} \ - ${FRONTEND_CONTAINER_NAME}=${HARBOR_REGISTRY_K8S}/${HARBOR_PROJECT}/${FRONTEND_IMAGE_NAME}:latest \ - -n vexplor || true - kubectl rollout restart deployment/${FRONTEND_DEPLOYMENT_NAME} -n vexplor - - echo "Frontend Rolling Update 진행 중..." - kubectl rollout status deployment/${FRONTEND_DEPLOYMENT_NAME} -n vexplor --timeout=5m - echo "Frontend 배포 완료" - FRONTEND_DEPLOY - - # Ingress 배포 - echo "Ingress 배포..." - ssh -p ${K8S_SSH_PORT} ${K8S_SSH_USER}@${K8S_SSH_HOST} "cd ~/vexplor-deploy && kubectl apply -f k8s/vexplor-ingress.yaml -n vexplor" - - echo "전체 배포 완료!" - - # 배포 검증 - - name: Verify deployment - run: | - echo "배포 검증..." - ssh -p ${K8S_SSH_PORT} ${K8S_SSH_USER}@${K8S_SSH_HOST} << 'VERIFY_SCRIPT' - echo "" - echo "Backend 상태:" - kubectl get deployment vexplor-backend -n vexplor - kubectl get pods -l app=vexplor-backend -n vexplor - echo "" - echo "Frontend 상태:" - kubectl get deployment vexplor-frontend -n vexplor - kubectl get pods -l app=vexplor-frontend -n vexplor - echo "" - echo "Services:" - kubectl get svc -n vexplor - echo "" - echo "Ingress:" - kubectl get ingress -n vexplor - echo "" - echo "검증 완료" - VERIFY_SCRIPT - - # 배포 요약 - - name: Deployment summary + # 빌드 완료 요약 + - name: Build summary if: success() run: | + echo "" echo "==========================================" - echo "배포가 성공적으로 완료되었습니다!" + echo " 이미지 빌드 & Push 완료!" echo "==========================================" + echo "" echo "빌드 버전: ${IMAGE_TAG}" - echo "Frontend: https://v1.vexplor.com" - echo "Backend API: https://api.vexplor.com" + echo "" + echo "푸시된 이미지:" + echo " - Backend: ${HARBOR_REGISTRY_EXTERNAL}/${HARBOR_PROJECT}/${BACKEND_IMAGE_NAME}:latest" + echo " - Frontend: ${HARBOR_REGISTRY_EXTERNAL}/${HARBOR_PROJECT}/${FRONTEND_IMAGE_NAME}:latest" + echo "" + echo "다음 단계:" + echo " - 공장 서버의 Watchtower가 자동으로 새 이미지를 감지합니다" + echo " - 또는 수동 업데이트: docker compose pull && docker compose up -d" + echo "" echo "==========================================" - # 실패 시 롤백 - - name: Rollback on failure - if: failure() - run: | - echo "배포 실패! 이전 버전으로 롤백..." - ssh -p ${K8S_SSH_PORT} ${K8S_SSH_USER}@${K8S_SSH_HOST} "kubectl rollout undo deployment/vexplor-backend -n vexplor" || true - ssh -p ${K8S_SSH_PORT} ${K8S_SSH_USER}@${K8S_SSH_HOST} "kubectl rollout undo deployment/vexplor-frontend -n vexplor" || true - # Harbor 로그아웃 - name: Logout from Harbor if: always() run: | export DOCKER_HOST=unix:///var/run/docker.sock docker logout ${HARBOR_REGISTRY} || true -