Merge pull request #53 from sumte-app/develop #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
| name: Sumte CD Workflow using github actions & docker compose | |
| on: | |
| push: | |
| branches: [ "main" ] # main 브랜치에 push될 때만 동작 | |
| workflow_dispatch: | |
| jobs: | |
| build-and-push-image: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up JDK 17 | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: '17' | |
| distribution: 'adopt' | |
| - name: Grant execute permission for gradlew | |
| run: chmod +x gradlew | |
| - name: Gradle Caching | |
| uses: actions/cache@v3 | |
| with: | |
| path: | | |
| ~/.gradle/caches | |
| ~/.gradle/wrapper | |
| key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} | |
| restore-keys: | | |
| ${{ runner.os }}-gradle- | |
| - name: Build jar | |
| run: ./gradlew clean --no-build-cache bootJar -x test #./gradlew --info clean bootJar -x test | |
| # Actuator 포함 여부 검증 | |
| - name: Assert actuator present | |
| run: | | |
| JAR=$(ls -t build/libs/*.jar | head -n1) | |
| echo "Checking newest JAR: $JAR" | |
| jar tf "$JAR" | grep spring-boot-actuator || { | |
| echo "❌ Actuator not found in $JAR"; exit 1 | |
| } | |
| - name: docker login | |
| uses: docker/login-action@v3 | |
| with: | |
| username: ${{ secrets.DOCKER_USERNAME }} | |
| password: ${{ secrets.DOCKER_PASSWORD }} | |
| - name: docker build and push | |
| uses: docker/build-push-action@v5.1.0 | |
| with: | |
| context: . | |
| push: true | |
| tags: ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_HUB_REPOSITORY }}:latest | |
| no-cache: true # 💡 매 빌드마다 새 이미지 | |
| pull: true # 💡 베이스 이미지도 최신으로 | |
| deploy: | |
| runs-on: ubuntu-latest | |
| needs: build-and-push-image | |
| steps: | |
| # - name: Load SSH key into agent | |
| # uses: webfactory/ssh-agent@v0.5.4 | |
| # with: | |
| # ssh-private-key: ${{ secrets.EC2_SSH_KEY }} | |
| # | |
| # - name: Test SSH | |
| # run: ssh -o StrictHostKeyChecking=no \ | |
| # ubuntu@${{ secrets.EC2_HOST }} whoami | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Copy compose file | |
| uses: appleboy/scp-action@v0.1.4 | |
| with: | |
| host: ${{ secrets.EC2_HOST }} | |
| username: ${{ secrets.EC2_USER }} | |
| key: ${{ secrets.EC2_SSH_KEY }} | |
| source: ./docker-compose.yml | |
| target: /home/ubuntu | |
| overwrite: true | |
| - name: SSH into EC2 and deploy | |
| uses: appleboy/ssh-action@v1.0.0 | |
| with: | |
| host: ${{ secrets.EC2_HOST }} | |
| username: ${{ secrets.EC2_USER }} | |
| key: ${{ secrets.EC2_SSH_KEY }} | |
| script: | | |
| set -eo pipefail | |
| # 디스크 청소 두 줄 / Docker 이미지, 로그 정리 | |
| docker system prune -af || true | |
| docker builder prune -af | |
| docker volume prune -f | |
| # Docker Compose V2 플러그인 설치 (Ubuntu 공식 레포) | |
| sudo apt-get update | |
| sudo apt-get install -y docker-compose-plugin | |
| docker compose version | |
| # 최신 이미지 pull | |
| docker pull ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_HUB_REPOSITORY }}:latest | |
| # .env 파일 생성 | |
| cat <<EOF > /home/ubuntu/.env | |
| SPRING_PROFILES_ACTIVE=prod | |
| EC2_HOST=${{ secrets.EC2_HOST }} | |
| DOCKER_HUB_USERNAME=${{ secrets.DOCKER_USERNAME }} | |
| DOCKER_HUB_REPOSITORY=${{ secrets.DOCKER_HUB_REPOSITORY }} | |
| RDS_HOST=${{ secrets.RDS_HOST }} | |
| RDS_PORT=${{ secrets.RDS_PORT }} | |
| RDS_DB=${{ secrets.RDS_DB }} | |
| RDS_USERNAME=${{ secrets.RDS_USERNAME }} | |
| RDS_PASSWORD=${{ secrets.RDS_PASSWORD }} | |
| JWT_SECRET=${{ secrets.JWT_SECRET }} | |
| S3_ACCESS_KEY=${{ secrets.S3_ACCESS_KEY }} | |
| S3_SECRET_KEY=${{ secrets.S3_SECRET_KEY }} | |
| KAKAOPAY_SECRET_KEY=${{ secrets.KAKAOPAY_SECRET_KEY }} | |
| EOF | |
| # .env 파일 권한 설정 | |
| chmod 600 /home/ubuntu/.env | |
| # 기존 app 컨테이너 강제 제거 (없어도 에러 무시) | |
| docker rm -f app || true | |
| # docker-compose로 재배포 | |
| docker compose -f /home/ubuntu/docker-compose.yml pull | |
| docker compose -f /home/ubuntu/docker-compose.yml up -d --force-recreate --remove-orphans | |
| - name: Send Discord Notification | |
| if: always() | |
| run: | | |
| STATUS="${{ job.status }}" | |
| if [ "$STATUS" == "success" ]; then | |
| EMOJI="✅" | |
| else | |
| EMOJI="❌" | |
| fi | |
| # 반복 폴링 헬스체크 | |
| HEALTH_STATUS="❌ 서버 비정상 작동" | |
| for i in {1..30}; do | |
| if curl -sSf https://sumteapi.duckdns.org/actuator/health >/dev/null; then | |
| HEALTH_STATUS="✅ 서버 정상 작동" | |
| break | |
| fi | |
| sleep 5 | |
| done | |
| MESSAGE="$EMOJI **sumte 배포 결과**\\n상태: $STATUS\\n$HEALTH_STATUS\\n🔗 프로젝트: ${{ github.repository }}\\n👤 커밋: ${{ github.actor }}" | |
| curl -H "Content-Type: application/json" \ | |
| -X POST \ | |
| -d "{\"content\": \"$MESSAGE\"}" \ | |
| ${{ secrets.DISCORD_WEBHOOK_URL }} || true | |