Skip to content

Merge remote-tracking branch 'origin/main' into deploy #20

Merge remote-tracking branch 'origin/main' into deploy

Merge remote-tracking branch 'origin/main' into deploy #20

# ===================================================================
# 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: 볼륨 마운트 활성화 여부
#
# ===================================================================