name: Deploy ASP.NET MVC to OCI on: push: branches: [ main, master, 'release/*' ] pull_request: branches: [ main, master ] jobs: build-and-deploy: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - name: Set build variables id: vars run: | if [[ "${{ github.ref }}" == "refs/heads/main" ]] || [[ "${{ github.ref }}" == "refs/heads/master" ]]; then echo "PLATFORM=linux/arm64" >> $GITHUB_OUTPUT echo "TARGET_ARCH=arm64" >> $GITHUB_OUTPUT echo "TAG_SUFFIX=" >> $GITHUB_OUTPUT echo "DEPLOY_ENV=production" >> $GITHUB_OUTPUT elif [[ "${{ github.ref }}" == refs/heads/release/* ]]; then echo "PLATFORM=linux/amd64" >> $GITHUB_OUTPUT echo "TARGET_ARCH=amd64" >> $GITHUB_OUTPUT echo "TAG_SUFFIX=-staging" >> $GITHUB_OUTPUT echo "DEPLOY_ENV=staging" >> $GITHUB_OUTPUT else echo "PLATFORM=linux/amd64" >> $GITHUB_OUTPUT echo "TARGET_ARCH=amd64" >> $GITHUB_OUTPUT echo "TAG_SUFFIX=-dev" >> $GITHUB_OUTPUT echo "DEPLOY_ENV=development" >> $GITHUB_OUTPUT fi - name: Cache Docker layers uses: actions/cache@v3 with: path: /tmp/.buildx-cache key: ${{ runner.os }}-buildx-${{ steps.vars.outputs.TARGET_ARCH }}-${{ github.sha }} restore-keys: | ${{ runner.os }}-buildx-${{ steps.vars.outputs.TARGET_ARCH }}- ${{ runner.os }}-buildx- - name: Build and push Docker image uses: docker/build-push-action@v4 with: context: . file: ./Dockerfile platforms: ${{ steps.vars.outputs.PLATFORM }} push: true tags: | registry.redecarneir.us/convertit:latest${{ steps.vars.outputs.TAG_SUFFIX }} registry.redecarneir.us/convertit:${{ github.sha }}${{ steps.vars.outputs.TAG_SUFFIX }} cache-from: | type=local,src=/tmp/.buildx-cache cache-to: | type=local,dest=/tmp/.buildx-cache-new,mode=max build-args: | BUILDKIT_INLINE_CACHE=1 TARGETARCH=${{ steps.vars.outputs.TARGET_ARCH }} - name: Move cache run: | rm -rf /tmp/.buildx-cache mv /tmp/.buildx-cache-new /tmp/.buildx-cache - name: Deploy to Production (ARM64) if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' uses: appleboy/ssh-action@v1.0.3 with: host: 129.146.116.218 username: ${{ secrets.SSH_USERNAME }} key: ${{ secrets.SSH_PRIVATE_KEY }} port: 22 timeout: 60s script: | # Para o container anterior da aplicação (se existir) docker stop convertit || true docker rm convertit || true # Remove imagem antiga docker rmi registry.redecarneir.us/convertit:latest || true # Puxa nova imagem ARM64 docker pull registry.redecarneir.us/convertit:latest # Executa o novo container na porta 80 com network host para acessar OpenSearch docker run -d \ --name convertit \ --restart unless-stopped \ --network host \ --memory=2g \ --cpus=1.5 \ --health-cmd="curl -f http://localhost:8082/health || exit 1" \ --health-interval=30s \ --health-timeout=10s \ --health-retries=3 \ --health-start-period=60s \ -e ASPNETCORE_ENVIRONMENT=Production \ -e ASPNETCORE_URLS="http://+:8082" \ -e DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false \ -e DOTNET_USE_POLLING_FILE_WATCHER=true \ -e DOTNET_EnableDiagnostics=0 \ -e DOTNET_RUNNING_IN_CONTAINER=true \ -e Serilog__OpenSearchUrl="http://localhost:9202" \ registry.redecarneir.us/convertit:latest # Limpa imagens não utilizadas docker image prune -f # Verifica se o container está rodando docker ps | grep convertit # Testa se a aplicação está respondendo na porta 8080 (com network host) sleep 10 curl -f http://localhost:8080 || echo "Aplicação pode estar inicializando..." - name: Deploy to Staging (x86_64) if: startsWith(github.ref, 'refs/heads/release/') uses: appleboy/ssh-action@v1.0.3 with: host: ${{ secrets.STAGING_HOST }} username: ${{ secrets.STAGING_SSH_USERNAME }} key: ${{ secrets.STAGING_SSH_PRIVATE_KEY }} port: 22 timeout: 60s script: | # Para o container anterior da aplicação staging (se existir) docker stop convertit-staging || true docker rm convertit-staging || true # Remove imagem antiga docker rmi registry.redecarneir.us/convertit:latest-staging || true # Puxa nova imagem x86_64 docker pull registry.redecarneir.us/convertit:latest-staging # Executa o novo container staging na porta 8080 docker run -d \ --name convertit-staging \ --restart unless-stopped \ --memory=1g \ --cpus=1.0 \ --health-cmd="curl -f http://localhost:8080/health || exit 1" \ --health-interval=30s \ --health-timeout=10s \ --health-retries=3 \ --health-start-period=60s \ -e ASPNETCORE_ENVIRONMENT=Staging \ -e ASPNETCORE_URLS="http://+:8082" \ -e DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false \ -e DOTNET_USE_POLLING_FILE_WATCHER=true \ -e DOTNET_EnableDiagnostics=0 \ -e DOTNET_RUNNING_IN_CONTAINER=true \ -e Serilog__OpenSearchUrl="http://localhost:9200" \ registry.redecarneir.us/convertit:latest-staging # Limpa imagens não utilizadas docker image prune -f # Verifica se o container está rodando docker ps | grep convertit-staging # Testa se a aplicação está respondendo na porta 8080 sleep 10 curl -f http://localhost:8080 || echo "Aplicação staging pode estar inicializando..." - name: Verify deployment if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' uses: appleboy/ssh-action@v1.0.3 with: host: 129.146.116.218 username: ${{ secrets.SSH_USERNAME }} key: ${{ secrets.SSH_PRIVATE_KEY }} port: 22 script: | echo "=== Status dos containers ===" docker ps -a | grep convertit echo "=== Logs da aplicação (últimas 20 linhas) ===" docker logs convertit --tail 20 echo "=== Teste de conectividade ===" curl -I http://localhost:8080 || echo "Aplicação ainda não está acessível" echo "=== Teste de conectividade OpenSearch ===" curl -I http://localhost:9202 || echo "OpenSearch não está acessível" - name: Verify staging deployment if: startsWith(github.ref, 'refs/heads/release/') uses: appleboy/ssh-action@v1.0.3 with: host: ${{ secrets.STAGING_HOST }} username: ${{ secrets.STAGING_SSH_USERNAME }} key: ${{ secrets.STAGING_SSH_PRIVATE_KEY }} port: 22 script: | echo "=== Status dos containers staging ===" docker ps -a | grep convertit-staging echo "=== Logs da aplicação staging (últimas 20 linhas) ===" docker logs convertit-staging --tail 20 echo "=== Teste de conectividade staging ===" curl -I http://localhost:8080 || echo "Aplicação staging ainda não está acessível"