fix: 스크립트 수정 #5
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: Deploy to OCI (Docker Hub) | |
| on: | |
| push: | |
| branches: | |
| - main | |
| - dev | |
| workflow_dispatch: | |
| env: | |
| PROJECT_NAME: madii-server | |
| IMAGE_NAME: mkkim999/madii-server | |
| jobs: | |
| build_and_push: | |
| name: Build and Push to Docker Hub | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Set up JDK 17 | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: 17 | |
| distribution: temurin | |
| - name: Grant execute permission for gradlew | |
| run: chmod +x ./gradlew | |
| - name: Make application-secret.yml | |
| run: echo "${{ secrets.APPLICATION_SECRET_BASE64 }}" | base64 --decode > ./src/main/resources/application-secret.yml | |
| - name: Make application-dev.yml | |
| run: echo "${{ secrets.APPLICATION_DEV_BASE64 }}" | base64 --decode > ./src/main/resources/application-dev.yml | |
| - name: Make application-prod.yml | |
| run: echo "${{ secrets.APPLICATION_PROD_BASE64 }}" | base64 --decode > ./src/main/resources/application-prod.yml | |
| - name: Create Firebase Admin SDK JSON | |
| uses: jsdaniell/[email protected] | |
| with: | |
| name: "madii-app-firebase-adminsdk-uriyk-c04677456f.json" | |
| json: ${{ secrets.FIREBASE_KEY_JSON }} | |
| dir: "src/main/resources/" | |
| - name: Gradle Caching | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.gradle/caches | |
| ~/.gradle/wrapper | |
| key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} | |
| restore-keys: | | |
| ${{ runner.os }}-gradle- | |
| - name: Build with Gradle | |
| run: ./gradlew build | |
| - name: Login to Docker Hub | |
| uses: docker/login-action@v3 | |
| with: | |
| username: ${{ secrets.DOCKER_HUB_ID }} | |
| password: ${{ secrets.DOCKER_HUB_PASSWORD }} | |
| - name: Build and push Docker image | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| file: ./Dockerfile | |
| push: true | |
| tags: | | |
| ${{ env.IMAGE_NAME }}:${{ github.sha }} | |
| ${{ env.IMAGE_NAME }}:latest | |
| cache-from: type=registry,ref=${{ env.IMAGE_NAME }}:latest | |
| cache-to: type=inline | |
| deploy: | |
| name: Deploy to OCI server | |
| needs: build_and_push | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Connect SSH & Deploy | |
| uses: appleboy/[email protected] | |
| with: | |
| host: ${{ secrets.OCI_HOST }} | |
| username: ${{ secrets.OCI_SSH_USER }} | |
| key: ${{ secrets.OCI_SSH_KEY }} | |
| port: 22 | |
| script: | | |
| set -euo pipefail | |
| IMAGE="${{ env.IMAGE_NAME }}:latest" | |
| CONTAINER_NAME="${{ env.PROJECT_NAME }}" | |
| NETWORK_NAME="madii-net" | |
| REDIS_CONTAINER="madii-redis" | |
| REDIS_IMAGE="redis:7-alpine" | |
| REDIS_VOLUME="madii-redis-data" | |
| echo "Deploying image: $IMAGE" | |
| # 1) Docker 없으면 설치 | |
| if ! command -v docker >/dev/null 2>&1; then | |
| echo "Docker not found. Installing..." | |
| curl -fsSL https://get.docker.com | sudo sh | |
| fi | |
| # 2) Docker Hub 로그인 (서버에서 pull 하기 위함) | |
| echo "${{ secrets.DOCKER_HUB_PASSWORD }}" | sudo docker login -u "${{ secrets.DOCKER_HUB_ID }}" --password-stdin | |
| # 3) 네트워크 보장 (컨테이너 DNS 위해 필수) | |
| sudo docker network inspect "$NETWORK_NAME" >/dev/null 2>&1 || sudo docker network create "$NETWORK_NAME" | |
| # 4) Redis 볼륨 보장 (재배포/재시작에도 데이터 유지) | |
| sudo docker volume inspect "$REDIS_VOLUME" >/dev/null 2>&1 || sudo docker volume create "$REDIS_VOLUME" | |
| # 5) Redis 컨테이너 보장 | |
| if ! sudo docker ps --format '{{.Names}}' | grep -qx "$REDIS_CONTAINER"; then | |
| sudo docker rm -f "$REDIS_CONTAINER" >/dev/null 2>&1 || true | |
| echo "Starting Redis container: $REDIS_CONTAINER" | |
| sudo docker run -d \ | |
| --name "$REDIS_CONTAINER" \ | |
| --network "$NETWORK_NAME" \ | |
| --restart unless-stopped \ | |
| -v "$REDIS_VOLUME:/data" \ | |
| "$REDIS_IMAGE" | |
| else | |
| if ! sudo docker inspect "$REDIS_CONTAINER" --format '{{json .NetworkSettings.Networks}}' | grep -q "\"$NETWORK_NAME\""; then | |
| sudo docker network connect "$NETWORK_NAME" "$REDIS_CONTAINER" || true | |
| fi | |
| fi | |
| # 6) 최신 이미지 pull | |
| sudo docker pull "$IMAGE" | |
| # 7) 기존 서버 컨테이너 정리 | |
| sudo docker stop "$CONTAINER_NAME" >/dev/null 2>&1 || true | |
| sudo docker rm "$CONTAINER_NAME" >/dev/null 2>&1 || true | |
| # 8) 새 서버 컨테이너 실행 (중요: Redis와 같은 네트워크로!) | |
| sudo docker run -d \ | |
| --name "$CONTAINER_NAME" \ | |
| --network "$NETWORK_NAME" \ | |
| --restart unless-stopped \ | |
| -p 8080:8080 \ | |
| -e SPRING_PROFILES_ACTIVE=prod \ | |
| "$IMAGE" | |
| # 9) Redis hostname 해석 체크 (실패 시 바로 알림) | |
| echo "Verifying container DNS..." | |
| sudo docker exec "$CONTAINER_NAME" sh -lc "getent hosts $REDIS_CONTAINER >/dev/null && echo 'OK: redis hostname resolves' || (echo 'FAIL: redis hostname not resolved' && exit 1)" | |
| # 10) dangling 이미지 정리 | |
| sudo docker image prune -f | |
| echo "Deploy finished." | |
| echo "Logs: sudo docker logs -f $CONTAINER_NAME" |