Merge pull request #183 from BSSMEOD/refactor/181-disposal-base-change #96
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
| name: CD - Docker Build & Deploy | |
| on: | |
| push: | |
| branches: [ "main", "master" ] | |
| workflow_dispatch: | |
| env: | |
| REGISTRY: ghcr.io | |
| jobs: | |
| build-and-push: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| steps: | |
| - name: 코드 체크아웃 | |
| uses: actions/checkout@v4 | |
| - name: Java 17 설정 | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: '17' | |
| distribution: 'temurin' | |
| cache: 'gradle' | |
| - name: Gradle 실행 권한 부여 | |
| run: chmod +x ./gradlew | |
| - name: 애플리케이션 JAR 빌드 | |
| run: ./gradlew bootJar --no-daemon -x test | |
| - name: QEMU 설정 (ARM64 크로스 컴파일) | |
| uses: docker/setup-qemu-action@v3 | |
| with: | |
| platforms: arm64 | |
| - name: 이미지 이름 소문자 변환 | |
| id: image_name | |
| run: | | |
| IMAGE_NAME=$(echo "${{ github.repository }}" | tr '[:upper:]' '[:lower:]') | |
| echo "name=${IMAGE_NAME}" >> $GITHUB_OUTPUT | |
| echo "소문자 변환된 이미지 이름: ${IMAGE_NAME}" | |
| - name: Docker Buildx 설정 | |
| uses: docker/setup-buildx-action@v3 | |
| - name: GitHub Container Registry 로그인 | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Docker 메타데이터 추출 | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ steps.image_name.outputs.name }} | |
| tags: | | |
| type=ref,event=branch | |
| type=sha,prefix={{branch}}- | |
| type=raw,value=latest,enable={{is_default_branch}} | |
| - name: Docker 이미지 빌드 및 푸시 | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| file: ./Dockerfile | |
| push: true | |
| platforms: linux/arm64 | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| cache-from: type=gha,scope=eod-build | |
| cache-to: type=gha,scope=eod-build,mode=max | |
| build-args: | | |
| BUILDKIT_INLINE_CACHE=1 | |
| - name: 이미지 다이제스트 출력 | |
| run: echo ${{ steps.meta.outputs.digest }} | |
| deploy: | |
| needs: build-and-push | |
| runs-on: ubuntu-latest | |
| if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' | |
| steps: | |
| - name: 서버에 SSH 접속 및 Docker Compose 배포 | |
| uses: appleboy/[email protected] | |
| with: | |
| host: ${{ secrets.SSH_HOST }} | |
| username: ${{ secrets.SSH_USERNAME }} | |
| key: ${{ secrets.SSH_KEY }} | |
| port: ${{ secrets.SSH_PORT || 22 }} | |
| script: | | |
| # 배포 디렉토리 생성 및 이동 | |
| mkdir -p ~/eod | |
| cd ~/eod | |
| # GitHub Repository Clone 또는 Pull | |
| if [ -d ".git" ]; then | |
| echo "기존 저장소 업데이트 중..." | |
| git fetch origin main | |
| git reset --hard origin/main | |
| else | |
| echo "저장소 복제 중..." | |
| rm -rf * .* 2>/dev/null || true | |
| git clone https://github.com/${{ github.repository }}.git . | |
| fi | |
| # .env 파일 생성 (GitHub Secrets 사용) | |
| REPO_LOWERCASE=$(echo "${{ github.repository }}" | tr '[:upper:]' '[:lower:]') | |
| cat > .env << EOF | |
| GITHUB_REPOSITORY=${REPO_LOWERCASE} | |
| SPRING_DATASOURCE_URL=${{ secrets.DB_URL }} | |
| SPRING_DATASOURCE_USERNAME=${{ secrets.DB_USERNAME }} | |
| SPRING_DATASOURCE_PASSWORD=${{ secrets.DB_PASSWORD }} | |
| MYSQL_ROOT_PASSWORD=${{ secrets.MYSQL_ROOT_PASSWORD }} | |
| MYSQL_DATABASE=${{ secrets.MYSQL_DATABASE }} | |
| MYSQL_USER=${{ secrets.DB_USERNAME }} | |
| MYSQL_PASSWORD=${{ secrets.DB_PASSWORD }} | |
| GOOGLE_CLIENT_ID=${{ secrets.GOOGLE_CLIENT_ID }} | |
| GOOGLE_CLIENT_SECRET=${{ secrets.GOOGLE_CLIENT_SECRET }} | |
| JWT_SECRET=${{ secrets.JWT_SECRET }} | |
| BASE_URL=${{ secrets.BASE_URL }} | |
| FRONTEND_BASE_URL=${{ secrets.FRONTEND_BASE_URL }} | |
| LOG_DIR=${{ secrets.LOG_DIR }} | |
| BSM_CLIENT_ID=${{ secrets.BSM_CLIENT_ID }} | |
| BSM_CLIENT_SECRET=${{ secrets.BSM_CLIENT_SECRET }} | |
| BSM_OAUTH_BASE_URL=${{ secrets.BSM_OAUTH_BASE_URL }} | |
| BSM_REDIRECT_URI=${{ secrets.BSM_REDIRECT_URI }} | |
| FILE_UPLOAD_BASE_URL=${{ secrets.FILE_UPLOAD_BASE_URL }} | |
| EOF | |
| # GitHub Container Registry 로그인 | |
| echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u ${{ github.actor }} --password-stdin | |
| # 환경 변수 확인 (디버깅) | |
| echo "GITHUB_REPOSITORY (소문자): ${REPO_LOWERCASE}" | |
| # MySQL 볼륨 존재 여부 확인 및 생성 | |
| echo "=========================================" | |
| echo "📦 MySQL 볼륨 확인 중..." | |
| if ! docker volume inspect eod_mysql-data-dev >/dev/null 2>&1; then | |
| echo "⚠️ 볼륨이 존재하지 않습니다. 새로 생성합니다..." | |
| docker volume create eod_mysql-data-dev | |
| echo "✅ 볼륨 생성 완료: eod_mysql-data-dev" | |
| else | |
| echo "✅ 볼륨이 이미 존재합니다: eod_mysql-data-dev" | |
| fi | |
| echo "=========================================" | |
| # Docker Compose로 배포 | |
| echo "=========================================" | |
| echo "🚀 Docker Compose 배포 시작" | |
| echo "=========================================" | |
| docker compose -f docker-compose.yml pull | |
| docker compose -f docker-compose.yml down | |
| docker compose -f docker-compose.yml up -d --remove-orphans | |
| # 배포 직후 상태 확인 | |
| echo "=========================================" | |
| echo "📊 배포 직후 컨테이너 상태:" | |
| docker compose -f docker-compose.yml ps | |
| echo "=========================================" | |
| # 컨테이너 시작 대기 | |
| echo "컨테이너 시작 대기 중..." | |
| sleep 10 | |
| # 사용하지 않는 이미지 정리 | |
| docker image prune -af | |
| - name: 배포 상태 확인 | |
| uses: appleboy/[email protected] | |
| with: | |
| host: ${{ secrets.SSH_HOST }} | |
| username: ${{ secrets.SSH_USERNAME }} | |
| key: ${{ secrets.SSH_KEY }} | |
| port: ${{ secrets.SSH_PORT || 22 }} | |
| script: | | |
| cd ~/eod | |
| echo "=========================================" | |
| echo "📋 환경 변수 확인 (민감 정보 마스킹):" | |
| cat .env | sed 's/PASSWORD=.*/PASSWORD=***/g' | sed 's/SECRET=.*/SECRET=***/g' | |
| echo "=========================================" | |
| echo "🐳 컨테이너 실행 상태:" | |
| docker compose -f docker-compose.yml ps | |
| # 컨테이너 실행 검증 (app 컨테이너가 반드시 떠있어야 함) | |
| if ! docker compose -f docker-compose.yml ps | grep -q "eod-app-dev.*Up"; then | |
| echo "❌ ERROR: app 컨테이너가 실행되지 않았습니다!" | |
| docker compose -f docker-compose.yml logs --tail=100 app | |
| exit 1 | |
| fi | |
| echo "✅ app 컨테이너 정상 실행 확인" | |
| echo "=========================================" | |
| echo "📊 Docker 이미지 확인:" | |
| docker images | grep eod || true | |
| echo "=========================================" | |
| echo "📝 MySQL 로그 (최근 20줄):" | |
| docker compose -f docker-compose.yml logs --tail=20 mysql || true | |
| echo "=========================================" | |
| echo "📝 애플리케이션 로그 (최근 50줄):" | |
| docker compose -f docker-compose.yml logs --tail=50 app || true | |
| echo "=========================================" | |
| echo "🔍 포트 사용 확인:" | |
| netstat -tuln | grep -E ':(8000|3306)' || true | |
| - name: 배포 완료 알림 | |
| if: success() | |
| run: | | |
| IMAGE_NAME=$(echo "${{ github.repository }}" | tr '[:upper:]' '[:lower:]') | |
| echo "✅ Docker Compose 배포 완료!" | |
| echo "서버: ${{ secrets.SSH_HOST }}" | |
| echo "이미지: ${{ env.REGISTRY }}/${IMAGE_NAME}:latest" |