🔧 settings: 위아원 #22
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 Backend to EC2 | |
| on: | |
| push: | |
| branches: | |
| - main | |
| - develop | |
| workflow_dispatch: | |
| env: | |
| REGISTRY: ghcr.io | |
| IMAGE_NAME: ${{ github.repository }} | |
| jobs: | |
| build-and-push: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| token: ${{ secrets.GHCR_TOKEN }} | |
| - name: Set up JDK 17 | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: '17' | |
| distribution: 'temurin' | |
| cache: 'gradle' | |
| - name: Make gradlew executable | |
| run: chmod +x gradlew | |
| - name: Copy properties files | |
| run: | | |
| mkdir -p src/main/resources | |
| cp config-submodule/application.properties src/main/resources/ | |
| cp config-submodule/application-prod.properties src/main/resources/ | |
| cp config-submodule/log4jdbc.log4j2.properties src/main/resources/ | |
| cp config-submodule/firebase-service-account.json src/main/resources/ | |
| - name: Build WAR | |
| run: ./gradlew build -x test --no-daemon | |
| - name: Convert to lowercase | |
| id: string | |
| run: | | |
| echo "IMAGE_NAME_LOWER=$(echo ${{ env.IMAGE_NAME }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT | |
| - name: Log in to GitHub Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GHCR_TOKEN }} | |
| - name: Build and push Docker image | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| file: ./Dockerfile | |
| push: true | |
| tags: | | |
| ${{ env.REGISTRY }}/${{ steps.string.outputs.IMAGE_NAME_LOWER }}:${{ github.ref_name }} | |
| ${{ env.REGISTRY }}/${{ steps.string.outputs.IMAGE_NAME_LOWER }}:latest | |
| deploy: | |
| needs: build-and-push | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Convert to lowercase | |
| id: string | |
| run: | | |
| echo "IMAGE_NAME_LOWER=$(echo ${{ env.IMAGE_NAME }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT | |
| - name: Deploy to EC2 | |
| uses: appleboy/ssh-action@v1.0.0 | |
| with: | |
| host: ${{ secrets.EC2_HOST }} | |
| username: ${{ secrets.EC2_USERNAME }} | |
| key: ${{ secrets.EC2_SSH_KEY }} | |
| script: | | |
| set -e | |
| # Set environment variables | |
| CONTAINER_NAME="itzeep-backend" | |
| PORT=8080 | |
| DATA_PATH="$HOME/apps/itzeep" | |
| ENV_FILE="$DATA_PATH/.env" | |
| COMPOSE_FILE="$DATA_PATH/docker-compose.yml" | |
| # Docker login to GHCR | |
| echo "${{ secrets.GHCR_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin | |
| # Pull new image | |
| docker pull ghcr.io/itzeep/backend:latest | |
| # Navigate to project directory | |
| cd $DATA_PATH | |
| # Check if .env file exists | |
| if [ ! -f .env ]; then | |
| echo "Error: .env file not found at $ENV_FILE" | |
| exit 1 | |
| fi | |
| # Update docker-compose.yml to use GHCR image | |
| sed -i "s|build:.*|image: ${{ secrets.IMAGE_NAME}}|g" docker-compose.yml | |
| sed -i "s|context:.*||g" docker-compose.yml | |
| sed -i "s|dockerfile:.*||g" docker-compose.yml | |
| # MongoDB와 Redis는 유지하고 백엔드만 재시작 | |
| # 기존 백엔드 컨테이너만 중지 | |
| docker-compose stop backend || true | |
| docker-compose rm -f backend || true | |
| # 백엔드 컨테이너만 재시작 | |
| docker-compose up -d backend | |
| # Wait for services to be healthy | |
| echo "Waiting for services to be healthy..." | |
| for i in {1..180}; do | |
| if docker-compose ps | grep -q "healthy"; then | |
| echo "Services are healthy!" | |
| break | |
| fi | |
| echo "Waiting... ($i/180)" | |
| sleep 5 | |
| done | |
| # Health check for application | |
| for i in {1..30}; do | |
| if curl -f http://localhost:8080/api/health 2>/dev/null; then | |
| echo "Backend application is healthy!" | |
| break | |
| fi | |
| if [ $i -eq 30 ]; then | |
| echo "Health check failed!" | |
| docker logs $CONTAINER_NAME --tail 50 | |
| exit 1 | |
| fi | |
| echo "Waiting for application... ($i/30)" | |
| sleep 10 | |
| done | |
| # Clean up Docker resources (이미지만 정리, 실행 중인 컨테이너는 유지) | |
| docker image prune -af | |
| # Show deployment status | |
| echo "📊 Current container status:" | |
| docker-compose ps | |
| # MongoDB와 Redis 상태 확인 | |
| echo "" | |
| echo "🔍 Checking MongoDB and Redis status..." | |
| docker exec itzeep-redis redis-cli ping && echo "✅ Redis is running" | |
| docker exec itzeep-mongo mongosh --eval "db.adminCommand('ping')" && echo "✅ MongoDB is running" | |
| echo "" | |
| echo "💾 Disk usage:" | |
| docker system df | |
| echo "" | |
| echo "🎉 Backend deployment completed successfully!" | |
| echo "📝 Note: MongoDB and Redis containers were preserved during deployment" | |