From 644dbf09747cbaf5f6bdb243640582ce9b9550ad Mon Sep 17 00:00:00 2001 From: Ricardo Carneiro Date: Mon, 27 Oct 2025 21:06:27 -0300 Subject: [PATCH] fix: deploy no swarm --- .gitea/workflows/deploy-bcards.yml | 147 +++++++++-------------------- deploy/cleanup-standalone.sh | 88 +++++++++++++++++ 2 files changed, 135 insertions(+), 100 deletions(-) create mode 100644 deploy/cleanup-standalone.sh diff --git a/.gitea/workflows/deploy-bcards.yml b/.gitea/workflows/deploy-bcards.yml index 1324f9f..16aa8ea 100644 --- a/.gitea/workflows/deploy-bcards.yml +++ b/.gitea/workflows/deploy-bcards.yml @@ -412,117 +412,64 @@ jobs: echo "🔍 File content (sensitive data masked):" cat appsettings.Production.json | sed 's/"[^"]*_[0-9A-Za-z_]*"/"***MASKED***"/g' - - name: Deploy to Production Servers + - name: Deploy to Production Swarm run: | - echo "🚀 Deploying to production servers (ARM64)..." - - # Configura SSH (igual ao QRRapido) + echo "🚀 Deploying to production Docker Swarm (ARM64)..." + + # Configura SSH mkdir -p ~/.ssh echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa - + # Adiciona hosts conhecidos ssh-keyscan -H 141.148.162.114 >> ~/.ssh/known_hosts ssh-keyscan -H 129.146.116.218 >> ~/.ssh/known_hosts - + # Testa a chave SSH ssh-add ~/.ssh/id_rsa 2>/dev/null || echo "SSH key loaded" - - # Upload configuration file to Server 1 - echo "📤 Uploading configuration to Server 1..." + + # Upload configuration and stack file to swarm manager + echo "📤 Uploading files to Swarm manager..." scp -o StrictHostKeyChecking=no appsettings.Production.json ubuntu@141.148.162.114:/tmp/ - - # Deploy no Servidor 1 (ARM - OCI) + scp -o StrictHostKeyChecking=no deploy/docker-stack.yml ubuntu@141.148.162.114:/tmp/ + + # Deploy to Docker Swarm ssh -o StrictHostKeyChecking=no ubuntu@141.148.162.114 << 'EOF' - echo "🔄 Atualizando Servidor 1..." - - # Create app config directory - mkdir -p /home/ubuntu/bcards-config - mv /tmp/appsettings.Production.json /home/ubuntu/bcards-config/ - - # Remove containers bcards-infrastructure se existirem - docker stop bcards-infrastructure bcards-test-app || true - docker rm bcards-infrastructure bcards-test-app || true - - # Para o container BCards atual se existir - docker stop bcards-prod || true - docker rm bcards-prod || true - - # Remove imagem antiga - docker rmi ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest || true - - # Puxa nova imagem - docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest - - # Executa novo container BCards - docker run -d \ - --name bcards-prod \ - --restart unless-stopped \ - --network host \ - -e ASPNETCORE_ENVIRONMENT=Production \ - -e ASPNETCORE_URLS=http://+:8080 \ - -e MongoDb__ConnectionString="mongodb://admin:c4rn31r0@129.146.116.218:27017,141.148.162.114:27017/BCardsDB?replicaSet=rs0&authSource=admin" \ - -e MongoDb__DatabaseName="BCardsDB" \ - -e Logging__LogLevel__Default=Debug \ - -e Serilog__OpenSearchUrl="http://localhost:9201" \ - -v /home/ubuntu/bcards-config/appsettings.Production.json:/app/appsettings.Production.json:ro \ - ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest - - # Debug: verificar configuração aplicada - echo "🔍 Verificando configuração MongoDB no container..." - docker logs bcards-prod | head -20 || echo "Container ainda iniciando..." - - # Recarrega NGINX - sudo nginx -t && sudo systemctl reload nginx - - echo "✅ Servidor 1 atualizado" - EOF - - # Upload configuration file to Server 2 - echo "📤 Uploading configuration to Server 2..." - scp -o StrictHostKeyChecking=no appsettings.Production.json ubuntu@129.146.116.218:/tmp/ - - # Deploy no Servidor 2 (ARM - OCI) - ssh -o StrictHostKeyChecking=no ubuntu@129.146.116.218 << 'EOF' - echo "🔄 Atualizando Servidor 2..." - - # Create app config directory - mkdir -p /home/ubuntu/bcards-config - mv /tmp/appsettings.Production.json /home/ubuntu/bcards-config/ - - # Remove containers bcards-infrastructure se existirem - docker stop bcards-infrastructure bcards-test-app || true - docker rm bcards-infrastructure bcards-test-app || true - - # Para o container BCards atual se existir - docker stop bcards-prod || true - docker rm bcards-prod || true - - # Remove imagem antiga - docker rmi ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest || true - - # Puxa nova imagem - docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest - - # Executa novo container BCards - docker run -d \ - --name bcards-prod \ - --restart unless-stopped \ - --network host \ - -e ASPNETCORE_ENVIRONMENT=Production \ - -e ASPNETCORE_URLS=http://+:8080 \ - -e MongoDb__ConnectionString="mongodb://admin:c4rn31r0@129.146.116.218:27017,141.148.162.114:27017/BCardsDB?replicaSet=rs0&authSource=admin" \ - -e MongoDb__DatabaseName="BCardsDB" \ - -e Logging__LogLevel__Default=Debug \ - -e Serilog__OpenSearchUrl="http://localhost:9202" \ - -v /home/ubuntu/bcards-config/appsettings.Production.json:/app/appsettings.Production.json:ro \ - ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest - - # Debug: verificar configuração aplicada - echo "🔍 Verificando configuração MongoDB no container..." - docker logs bcards-prod | head -20 || echo "Container ainda iniciando..." - - echo "✅ Servidor 2 atualizado" + set -e + + echo "🔄 Updating Docker Swarm stack..." + + # Update Docker config with new appsettings + echo "📝 Updating bcards-appsettings config..." + + # Remove old config (will fail if in use, that's ok - swarm will use it until update) + docker config rm bcards-appsettings 2>/dev/null || echo "Config in use or doesn't exist, will create new one" + + # Create new config with timestamp to force update + CONFIG_NAME="bcards-appsettings-$(date +%s)" + docker config create ${CONFIG_NAME} /tmp/appsettings.Production.json + + # Update stack file to use new config name + sed "s/bcards-appsettings/${CONFIG_NAME}/g" /tmp/docker-stack.yml > /tmp/docker-stack-updated.yml + + echo "🐳 Deploying stack to Swarm (rolling update, zero downtime)..." + docker stack deploy -c /tmp/docker-stack-updated.yml bcards --with-registry-auth + + echo "⏳ Waiting for service to update..." + sleep 10 + + # Show service status + docker service ls --filter name=bcards_bcards-app + docker service ps bcards_bcards-app --no-trunc --filter "desired-state=running" | head -10 + + echo "🧹 Cleaning up standalone containers if they exist..." + docker stop bcards-prod 2>/dev/null || echo "No standalone container to stop" + docker rm bcards-prod 2>/dev/null || echo "No standalone container to remove" + + # Clean up temp files + rm -f /tmp/appsettings.Production.json /tmp/docker-stack.yml /tmp/docker-stack-updated.yml + + echo "✅ Swarm stack updated successfully!" EOF - name: Health Check Production diff --git a/deploy/cleanup-standalone.sh b/deploy/cleanup-standalone.sh new file mode 100644 index 0000000..895dcf3 --- /dev/null +++ b/deploy/cleanup-standalone.sh @@ -0,0 +1,88 @@ +#!/bin/bash +# Script para limpar containers standalone do BCards +# Deve ser executado DEPOIS que o Swarm estiver rodando corretamente + +set -e + +echo "🔍 Verificando containers standalone do BCards..." + +# Lista de possíveis nomes de containers standalone +STANDALONE_CONTAINERS=( + "bcards-prod" + "bcards-release" + "bcards-app" +) + +# Verifica se o Swarm está rodando +echo "✅ Verificando status do Docker Swarm..." +if ! docker info | grep -q "Swarm: active"; then + echo "❌ ERRO: Docker Swarm não está ativo neste servidor!" + echo "Este script só deve ser executado em servidores do Swarm." + exit 1 +fi + +# Verifica se o serviço do Swarm está rodando +echo "✅ Verificando serviço bcards_bcards-app no Swarm..." +if ! docker service ls | grep -q "bcards_bcards-app"; then + echo "❌ ERRO: Serviço bcards_bcards-app não encontrado no Swarm!" + echo "Certifique-se de que o deploy do Swarm foi feito antes de executar este script." + exit 1 +fi + +# Mostra status do serviço Swarm +echo "" +echo "📊 Status atual do serviço Swarm:" +docker service ls --filter name=bcards_bcards-app +echo "" +docker service ps bcards_bcards-app --filter "desired-state=running" | head -10 +echo "" + +# Verifica se há containers standalone rodando +FOUND_CONTAINERS=false +for container_name in "${STANDALONE_CONTAINERS[@]}"; do + if docker ps -a --format '{{.Names}}' | grep -q "^${container_name}$"; then + FOUND_CONTAINERS=true + break + fi +done + +if [ "$FOUND_CONTAINERS" = false ]; then + echo "✅ Nenhum container standalone encontrado. Sistema está OK!" + exit 0 +fi + +# Lista containers encontrados +echo "⚠️ Containers standalone encontrados:" +for container_name in "${STANDALONE_CONTAINERS[@]}"; do + if docker ps -a --format '{{.Names}}' | grep -q "^${container_name}$"; then + echo " - $container_name" + docker ps -a --filter "name=^${container_name}$" --format "table {{.ID}}\t{{.Names}}\t{{.Status}}\t{{.Ports}}" + fi +done +echo "" + +# Pergunta confirmação +read -p "🗑️ Deseja remover estes containers standalone? (sim/não): " -r +echo +if [[ ! $REPLY =~ ^[Ss][Ii][Mm]$ ]]; then + echo "❌ Operação cancelada pelo usuário." + exit 0 +fi + +# Remove os containers +echo "🧹 Removendo containers standalone..." +for container_name in "${STANDALONE_CONTAINERS[@]}"; do + if docker ps -a --format '{{.Names}}' | grep -q "^${container_name}$"; then + echo " Parando e removendo: $container_name" + docker stop "$container_name" 2>/dev/null || true + docker rm "$container_name" 2>/dev/null || true + fi +done + +echo "" +echo "✅ Limpeza concluída!" +echo "" +echo "📊 Status final do serviço Swarm:" +docker service ls --filter name=bcards_bcards-app +echo "" +docker service ps bcards_bcards-app --filter "desired-state=running" | head -10