Merge remote-tracking branch 'origin/main' into deploy #20
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # =================================================================== | |
| # Spring Boot 전용 CI/CD 배포 워크플로우 | |
| # =================================================================== | |
| name: PROJECT-SPRING-SYNOLOGY-CICD | |
| # =================================================================== | |
| # 📋 필수 GitHub Secrets 설정 가이드 | |
| # =================================================================== | |
| # | |
| # ⚠️ 사용하기 전에 반드시 다음 GitHub Secrets를 설정하세요! | |
| # (저장소 Settings > Secrets and variables > Actions에서 설정) | |
| # | |
| # 🔧 필수 Secrets: | |
| # ┌─────────────────────────────┬────────────────────────────────────┐ | |
| # │ Secret 이름 │ 설명 │ | |
| # ├─────────────────────────────┼────────────────────────────────────┤ | |
| # │ APPLICATION_PROD_YML │ Spring Boot 운영 설정 파일 내용 │ | |
| # │ DOCKERHUB_USERNAME │ DockerHub 사용자명 │ | |
| # │ DOCKERHUB_TOKEN │ DockerHub 액세스 토큰 │ | |
| # │ SERVER_HOST │ 배포 대상 서버 IP/도메인 │ | |
| # │ SERVER_USER │ 서버 SSH 접속 사용자명 │ | |
| # │ SERVER_PASSWORD │ 서버 SSH 접속 비밀번호 │ | |
| # └─────────────────────────────┴────────────────────────────────────┘ | |
| # | |
| # 🌐 포트 및 컨테이너 설정 (워크플로우 env 섹션에서 설정): | |
| # ┌─────────────────────────────┬────────────────────────────────────┐ | |
| # │ DEPLOY_PORT │ deploy/main 브랜치 배포 포트 │ | |
| # │ CONTAINER_NAME │ Docker 컨테이너 이름 │ | |
| # │ │ (기본값: PROJECT_NAME) │ | |
| # ├─────────────────────────────┼────────────────────────────────────┤ | |
| # │ ENABLE_VOLUME_MOUNT │ 볼륨 마운트 활성화 (true/false) │ | |
| # │ VOLUME_HOST_PATH │ 호스트 볼륨 경로 │ | |
| # │ VOLUME_CONTAINER_PATH │ 컨테이너 내부 마운트 경로 │ | |
| # └─────────────────────────────┴────────────────────────────────────┘ | |
| # | |
| # 💡 포트 설정 예시 (env 섹션에서 변경): | |
| # DEPLOY_PORT: "8092" # 배포 서비스 포트 | |
| # | |
| # ⚠️ 주의사항: | |
| # 1. 포트는 서버에서 사용하지 않는 포트를 선택하세요 | |
| # 2. 방화벽에서 해당 포트가 열려있는지 확인하세요 | |
| # 3. 다른 프로젝트와 포트가 겹치지 않도록 주의하세요 | |
| # | |
| # 📝 APPLICATION_PROD_YML 예시: | |
| # spring: | |
| # datasource: | |
| # url: jdbc:mysql://localhost:3306/your_db | |
| # username: your_username | |
| # password: your_password | |
| # jpa: | |
| # hibernate: | |
| # ddl-auto: update | |
| # | |
| # =================================================================== | |
| # | |
| # 🚀 워크플로우 기능: | |
| # - Spring Boot 프로젝트 Gradle 빌드 | |
| # - Docker 이미지 생성 및 DockerHub 푸시 | |
| # - SSH를 통한 원격 서버 배포 | |
| # - 브랜치별 다른 포트 및 컨테이너 관리 | |
| # - 포트 충돌 방지를 위한 환경변수 기반 포트 설정 | |
| # | |
| # 🌿 브랜치별 배포 전략: | |
| # - deploy 브랜치: 배포 환경 (DEPLOY_PORT 사용) | |
| # - main 브랜치: 배포 환경 (수동 실행시, DEPLOY_PORT 사용) | |
| # | |
| # 📝 사용 방법: | |
| # 1. 위의 GitHub Secrets 설정 | |
| # 2. 아래 env 섹션에서 PROJECT_NAME, DEPLOY_PORT 등 설정 | |
| # 3. deploy 브랜치에 push하면 자동으로 CI/CD 실행 (main 브랜치는 수동 실행만 가능) | |
| # | |
| # =================================================================== | |
| # =================================================================== | |
| # 트리거 설정 | |
| # =================================================================== | |
| # deploy 브랜치에 push할 때 자동으로 CI/CD가 실행됩니다. | |
| # main 브랜치는 workflow_dispatch로 수동 실행만 가능합니다. | |
| on: | |
| push: | |
| branches: | |
| - deploy # 배포 환경 (DEPLOY_PORT 사용) | |
| workflow_dispatch: # 수동 실행 허용 | |
| # =================================================================== | |
| # 환경 변수 설정 | |
| # =================================================================== | |
| env: | |
| # 🔧 프로젝트 설정 - 실제 프로젝트명으로 변경하세요 | |
| PROJECT_NAME: "mapsy-back" # 기본값: project (프로젝트명에 맞게 수정 필요) | |
| # 🐳 Docker 설정 | |
| DOCKER_IMAGE_PREFIX: "back-container" | |
| # ☁️ Spring Boot 설정 | |
| SPRING_PROFILE: "prod" | |
| JAVA_VERSION: "21" | |
| GRADLE_OPTS: "-Dspring.profiles.active=prod" | |
| # 📁 경로 설정 | |
| APPLICATION_YML_DIR: "MS-Web/src/main/resources" | |
| # 🌐 포트 설정 | |
| DEPLOY_PORT: "8096" # deploy/main 브랜치 배포 포트 | |
| # 🐳 컨테이너 이름 설정 | |
| # 비워두면 PROJECT_NAME을 기본값으로 사용 (예: mapsy-back) | |
| # 커스텀 이름을 원하면 직접 입력 (예: "my-custom-container") | |
| CONTAINER_NAME: "" | |
| # 📦 볼륨 마운트 설정 | |
| # true: 볼륨 마운트 활성화 (디렉토리 없으면 자동 생성) | |
| # false: 볼륨 마운트 비활성화 (기본값) | |
| ENABLE_VOLUME_MOUNT: "false" | |
| VOLUME_HOST_PATH: "/volume1/projects/mapsy" # 호스트 경로 | |
| VOLUME_CONTAINER_PATH: "/mnt" # 컨테이너 내부 경로 | |
| jobs: | |
| # =================================================================== | |
| # 빌드 작업 | |
| # =================================================================== | |
| build: | |
| name: Spring Boot 애플리케이션 빌드 | |
| runs-on: ubuntu-latest | |
| steps: | |
| # 1. 소스코드 체크아웃 | |
| - name: 코드 체크아웃 | |
| uses: actions/checkout@v4 | |
| # 2. Java 개발 환경 설정 | |
| - name: Java 설정 | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: ${{ env.JAVA_VERSION }} | |
| distribution: 'temurin' | |
| cache: 'gradle' | |
| # 3. Gradle 실행 권한 부여 | |
| - name: Gradle Wrapper 실행권한 부여 | |
| run: chmod +x gradlew | |
| # 4. Spring Boot 운영 환경 설정 파일 생성 | |
| # GitHub Secrets에서 APPLICATION_PROD_YML 값을 읽어와서 | |
| # 리소스 디렉토리에 파일로 생성 | |
| - name: application-prod.yml 생성 | |
| run: | | |
| # 리소스 디렉토리 생성 (환경변수 사용) | |
| mkdir -p ${{ env.APPLICATION_YML_DIR }} | |
| # GitHub Secrets의 APPLICATION_PROD_YML 내용을 파일로 저장 | |
| cat << 'EOF' > ./${{ env.APPLICATION_YML_DIR }}/application-prod.yml | |
| ${{ secrets.APPLICATION_PROD_YML }} | |
| EOF | |
| echo "✅ application-prod.yml 파일 생성 완료 (${{ env.APPLICATION_YML_DIR }})" | |
| # 4-1. Firebase Service Account JSON 파일 생성 | |
| # GitHub Secrets에서 FIREBASE_KEY_JSON 값을 읽어와서 | |
| # 리소스 디렉토리에 mapsy-fcm.json 파일로 생성 | |
| - name: mapsy-fcm.json 생성 (Firebase) | |
| run: | | |
| cat << 'EOF' > ./${{ env.APPLICATION_YML_DIR }}/mapsy-fcm.json | |
| ${{ secrets.FIREBASE_KEY_JSON }} | |
| EOF | |
| echo "✅ mapsy-fcm.json 파일 생성 완료 (${{ env.APPLICATION_YML_DIR }})" | |
| # 5. Gradle 빌드 실행 | |
| # 테스트는 제외하고 운영 프로파일로 빌드 | |
| - name: Build with Gradle | |
| run: ./gradlew clean build -x test ${{ env.GRADLE_OPTS }} | |
| # 6. Docker 빌드 환경 설정 | |
| - name: Docker 빌드환경 설정 | |
| uses: docker/setup-buildx-action@v3 | |
| # 7. DockerHub 로그인 | |
| - name: DockerHub 로그인 | |
| uses: docker/login-action@v3 | |
| with: | |
| username: ${{ secrets.DOCKERHUB_USERNAME }} | |
| password: ${{ secrets.DOCKERHUB_TOKEN }} | |
| # 8. Docker 레이어 캐싱 설정 | |
| # 빌드 속도 향상을 위한 캐시 설정 | |
| - name: Cache Docker layers | |
| uses: actions/cache@v4 | |
| with: | |
| path: /tmp/.buildx-cache | |
| key: ${{ runner.os }}-buildx-${{ hashFiles('Dockerfile') }} | |
| restore-keys: | | |
| ${{ runner.os }}-buildx- | |
| # 9. Docker 이미지 빌드 및 푸시 | |
| # 브랜치명을 태그로 사용하여 main/test 환경별로 이미지 관리 | |
| - name: Docker 이미지 빌드 및 푸시 | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| file: ./Dockerfile | |
| push: true | |
| tags: ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.PROJECT_NAME }}-${{ env.DOCKER_IMAGE_PREFIX }}:${{ github.ref_name }} | |
| cache-from: type=local,src=/tmp/.buildx-cache | |
| cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max | |
| # 10. Docker 캐시 정리 | |
| - name: Move Docker cache | |
| run: | | |
| rm -rf /tmp/.buildx-cache | |
| mv /tmp/.buildx-cache-new /tmp/.buildx-cache | |
| # =================================================================== | |
| # 배포 작업 | |
| # =================================================================== | |
| deploy: | |
| name: 원격 서버 배포 | |
| needs: build | |
| runs-on: ubuntu-latest | |
| steps: | |
| # SSH를 통한 원격 서버 배포 실행 | |
| - name: Deploy | |
| uses: appleboy/ssh-action@v1.0.3 | |
| with: | |
| host: ${{ secrets.SERVER_HOST }} | |
| username: ${{ secrets.SERVER_USER }} | |
| password: ${{ secrets.SERVER_PASSWORD }} | |
| port: 2022 | |
| script: | | |
| set -e | |
| # ============================================================ | |
| # 배포 환경 변수 설정 | |
| # ============================================================ | |
| echo "🔧 환경변수 설정.." | |
| export PATH=$PATH:/usr/local/bin | |
| export PW=${{ secrets.SERVER_PASSWORD }} | |
| # GitHub에서 전달받은 브랜치명 | |
| BRANCH=${{ github.ref_name }} | |
| # 프로젝트 설정 | |
| PROJECT_NAME="${{ env.PROJECT_NAME }}" | |
| # ============================================================ | |
| # 포트 및 컨테이너명 설정 | |
| # ============================================================ | |
| PORT=${{ env.DEPLOY_PORT }} | |
| # 컨테이너 이름 설정 (환경변수가 비어있으면 PROJECT_NAME을 기본값으로 사용) | |
| if [ -z "${{ env.CONTAINER_NAME }}" ]; then | |
| CONTAINER_NAME="${PROJECT_NAME}" | |
| echo "ℹ️ CONTAINER_NAME이 설정되지 않아 PROJECT_NAME을 사용합니다: $CONTAINER_NAME" | |
| else | |
| CONTAINER_NAME="${{ env.CONTAINER_NAME }}" | |
| echo "ℹ️ 사용자 지정 CONTAINER_NAME 사용: $CONTAINER_NAME" | |
| fi | |
| echo "🚀 배포 환경으로 배포합니다 (브랜치: $BRANCH)" | |
| # 설정 정보 출력 | |
| echo "📋 배포 설정 정보:" | |
| echo " - 브랜치: $BRANCH" | |
| echo " - 프로젝트: $PROJECT_NAME" | |
| echo " - 컨테이너 이름: $CONTAINER_NAME" | |
| echo " - 포트: $PORT" | |
| echo " - Docker 이미지: ${{ secrets.DOCKERHUB_USERNAME }}/${PROJECT_NAME}-${{ env.DOCKER_IMAGE_PREFIX }}:${BRANCH}" | |
| # ============================================================ | |
| # Docker 이미지 풀 (Pull) | |
| # ============================================================ | |
| echo "⬇️ Docker 이미지 풀: ${{ secrets.DOCKERHUB_USERNAME }}/${PROJECT_NAME}-${{ env.DOCKER_IMAGE_PREFIX }}:${BRANCH}" | |
| echo $PW | sudo -S docker pull ${{ secrets.DOCKERHUB_USERNAME }}/${PROJECT_NAME}-${{ env.DOCKER_IMAGE_PREFIX }}:${BRANCH} | |
| # ============================================================ | |
| # 기존 컨테이너 정리 | |
| # ============================================================ | |
| echo "🧹 컨테이너 $CONTAINER_NAME 존재 여부 확인 중..." | |
| # 동일한 이름의 컨테이너가 존재하는지 확인 | |
| if sudo docker ps -a --format '{{.Names}}' | grep -Eq "^${CONTAINER_NAME}\$"; then | |
| echo "⚠️ 컨테이너 $CONTAINER_NAME 이(가) 존재합니다. 중지 및 삭제 중..." | |
| echo $PW | sudo -S docker rm -f $CONTAINER_NAME | |
| echo "✅ 컨테이너 $CONTAINER_NAME 이(가) 삭제되었습니다." | |
| else | |
| echo "ℹ️ 존재하는 컨테이너 $CONTAINER_NAME 이(가) 없습니다." | |
| fi | |
| # ============================================================ | |
| # 새 컨테이너 실행 | |
| # ============================================================ | |
| echo "🚀 새로운 컨테이너 $CONTAINER_NAME 실행 중..." | |
| # 볼륨 마운트 옵션 설정 | |
| VOLUME_MOUNT_OPTION="" | |
| if [ "${{ env.ENABLE_VOLUME_MOUNT }}" == "true" ]; then | |
| # 디렉토리가 없으면 생성 | |
| if [ ! -d "${{ env.VOLUME_HOST_PATH }}/${PROJECT_NAME}" ]; then | |
| echo "📁 볼륨 마운트 디렉토리 생성: ${{ env.VOLUME_HOST_PATH }}/${PROJECT_NAME}" | |
| echo $PW | sudo -S mkdir -p "${{ env.VOLUME_HOST_PATH }}/${PROJECT_NAME}" | |
| fi | |
| VOLUME_MOUNT_OPTION="-v ${{ env.VOLUME_HOST_PATH }}/${PROJECT_NAME}:${{ env.VOLUME_CONTAINER_PATH }}/${PROJECT_NAME}" | |
| echo "📦 볼륨 마운트 활성화: $VOLUME_MOUNT_OPTION" | |
| else | |
| echo "ℹ️ 볼륨 마운트 비활성화됨" | |
| fi | |
| # Docker 컨테이너 실행 | |
| # - 포트 매핑: ${PORT}:8080 (외부포트:내부포트) | |
| # - 시간대: Asia/Seoul | |
| # - Spring 프로파일: prod | |
| # - 볼륨 마운트: ENABLE_VOLUME_MOUNT=true일 때만 활성화 | |
| echo $PW | sudo -S docker run -d \ | |
| -p ${PORT}:8080 \ | |
| --name $CONTAINER_NAME \ | |
| -e TZ=Asia/Seoul \ | |
| -e "SPRING_PROFILES_ACTIVE=${{ env.SPRING_PROFILE }}" \ | |
| -v /etc/localtime:/etc/localtime:ro \ | |
| $VOLUME_MOUNT_OPTION \ | |
| ${{ secrets.DOCKERHUB_USERNAME }}/${PROJECT_NAME}-${{ env.DOCKER_IMAGE_PREFIX }}:${BRANCH} | |
| # ============================================================ | |
| # 배포 완료 확인 | |
| # ============================================================ | |
| echo "✅ 배포가 성공적으로 완료되었습니다!" | |
| echo "" | |
| echo "📋 배포 결과 요약:" | |
| echo " 🎯 프로젝트: $PROJECT_NAME" | |
| echo " 🌿 브랜치: $BRANCH" | |
| echo " 🐳 컨테이너: $CONTAINER_NAME" | |
| echo " 🌐 포트: $PORT" | |
| echo " ⏰ 배포 시간: $(date '+%Y-%m-%d %H:%M:%S')" | |
| echo "" | |
| echo "🔗 접속 URL: http://${{ secrets.SERVER_HOST }}:${PORT}" | |
| # =================================================================== | |
| # 사용 예시 | |
| # =================================================================== | |
| # | |
| # 현재 설정: deploy 브랜치에 push할 때 자동 배포 | |
| # main 브랜치는 수동 실행(workflow_dispatch)만 가능 | |
| # | |
| # 포트 설정 (env 섹션에서 설정): | |
| # - deploy/main: DEPLOY_PORT (기본: 8092) | |
| # | |
| # 필요한 Secrets: | |
| # - APPLICATION_PROD_YML, DOCKERHUB_*, SERVER_* (필수) | |
| # | |
| # env 섹션에서 설정하는 값들: | |
| # - PROJECT_NAME: 프로젝트명 | |
| # - DEPLOY_PORT: 배포 포트 | |
| # - CONTAINER_NAME: 컨테이너 이름 (기본값: PROJECT_NAME) | |
| # - ENABLE_VOLUME_MOUNT: 볼륨 마운트 활성화 여부 | |
| # | |
| # =================================================================== |