# Configura para interromper a execucao em caso de qualquer erro $ErrorActionPreference = "Stop" $remoteHost = "root@iris.haven" $remoteBuildDir = "/tmp/mindforge-build" # --- Funcoes auxiliares --- function Test-SshConnection { param([string]$HostName) try { $null = ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no -o BatchMode=yes $HostName "echo ok" 2>$null return $true } catch { return $false } } function Invoke-RemoteBuild { Write-Host "Preparando build remoto no host $remoteHost..." -ForegroundColor Cyan # Cria diretorio temporario no remoto ssh -o StrictHostKeyChecking=no $remoteHost "rm -rf $remoteBuildDir && mkdir -p $remoteBuildDir" if ($LASTEXITCODE -ne 0) { Write-Error "Falha ao criar diretorio remoto." exit 1 } # Compacta o projeto (excluindo artefatos de build e arquivos desnecessarios) Write-Host "Compactando arquivos do projeto..." $tempTar = "$env:TEMP\mindforge-build.tar.gz" $excludes = @( "--exclude=.git", "--exclude=node_modules", "--exclude=bin", "--exclude=obj", "--exclude=.vs", "--exclude=.vscode", "--exclude=.cache", "--exclude=dist", "--exclude=.idea", "--exclude=*.user", "--exclude=appsettings.Development.json" ) & tar czf $tempTar $excludes -C (Get-Location) . if ($LASTEXITCODE -ne 0) { Write-Error "Falha ao compactar arquivos do projeto." exit 1 } # Envia o arquivo compactado para o host remoto Write-Host "Enviando arquivos do projeto para o host remoto..." scp -O -o StrictHostKeyChecking=no $tempTar "${remoteHost}:${remoteBuildDir}/project.tar.gz" if ($LASTEXITCODE -ne 0) { Write-Error "Falha ao enviar arquivos para o host remoto." Remove-Item -Force $tempTar -ErrorAction SilentlyContinue exit 1 } # Remove o arquivo temporario local Remove-Item -Force $tempTar -ErrorAction SilentlyContinue # Extrai no host remoto Write-Host "Extraindo arquivos no host remoto..." ssh -o StrictHostKeyChecking=no $remoteHost "cd $remoteBuildDir && tar xzf project.tar.gz && rm project.tar.gz" if ($LASTEXITCODE -ne 0) { Write-Error "Falha ao extrair arquivos no host remoto." ssh -o StrictHostKeyChecking=no $remoteHost "rm -rf $remoteBuildDir" exit 1 } # Garante que o builder buildx existe no remoto Write-Host "Verificando builder Buildx no remoto..." ssh -o StrictHostKeyChecking=no $remoteHost "docker buildx inspect mindforge-builder 2>/dev/null || docker buildx create --name mindforge-builder --use" # Executa o build no remoto Write-Host "Compilando as imagens Docker no host remoto..." ssh -o StrictHostKeyChecking=no $remoteHost "cd $remoteBuildDir && docker buildx bake --load" if ($LASTEXITCODE -ne 0) { Write-Error "Falha na compilacao remota." # Limpa diretorio remoto mesmo em caso de falha ssh -o StrictHostKeyChecking=no $remoteHost "rm -rf $remoteBuildDir" exit 1 } # Limpa diretorio remoto ssh -o StrictHostKeyChecking=no $remoteHost "rm -rf $remoteBuildDir" } # --- Logica principal --- # Verifica se o executavel 'docker' esta disponivel no PATH $dockerCliAvailable = $false if (Get-Command "docker" -ErrorAction SilentlyContinue) { $dockerCliAvailable = $true } if ($dockerCliAvailable) { # --- Modo local (Docker CLI presente) --- # Habilita o BuildKit para compilacoes com 'docker build' padrao $env:DOCKER_BUILDKIT = "1" # Testa se o daemon do Docker local esta rodando $localDaemonRunning = $false try { $null = docker version --format '{{.Server.Version}}' 2>$null $localDaemonRunning = $true } catch { $localDaemonRunning = $false } if (-not $localDaemonRunning) { Write-Host "O daemon local do Docker nao esta rodando. Redirecionando comandos para o host remoto $remoteHost..." $env:DOCKER_HOST = "ssh://$remoteHost" # Testa a conexao com o host remoto try { $null = docker version --format '{{.Server.Version}}' 2>$null Write-Host "Conexao com o host remoto estabelecida com sucesso!" } catch { Write-Error "Nao foi possivel conectar ao Docker local nem ao host remoto $remoteHost. Certifique-se de que o Docker Desktop local esta iniciado ou que o servidor remoto esta acessivel." exit 1 } } # Detecta se o Docker Buildx esta disponivel $buildxAvailable = $false try { $null = docker buildx version 2>$null $buildxAvailable = $true } catch { $buildxAvailable = $false } if ($buildxAvailable) { # Garante que o builder padrao do buildx existe e esta ativo try { $null = docker buildx inspect mindforge-builder 2>$null Write-Host "Usando builder 'mindforge-builder' existente..." } catch { Write-Host "Criando e configurando builder 'mindforge-builder'..." docker buildx create --name mindforge-builder --use } # Compila as imagens usando o docker buildx bake Write-Host "Compilando as imagens Docker usando o Buildx..." docker buildx bake --load } else { # Fallback: build tradicional sem buildx $env:DOCKER_BUILDKIT = "0" Write-Warning "O plugin Docker Buildx nao foi encontrado. Executando build padrao (single-arch) local para cada servico..." # Detecta a arquitetura do sistema para passar como build-arg $sysArch = "$env:PROCESSOR_ARCHITECTURE".ToLower() $dockerArch = if ($sysArch -eq "amd64") { "amd64" } else { $sysArch } $buildArgs = "--build-arg TARGETARCH=$dockerArch --build-arg TARGETOS=linux --build-arg BUILDPLATFORM=linux/$dockerArch" Write-Host "Compilando Mindforge.Web..." docker build -t git.ivanch.me/ivanch/mindforge-web:latest ./Mindforge.Web --build-arg VITE_API_BASE_URL=http://api.mindforge.haven Write-Host "Compilando Mindforge.API..." docker build -t git.ivanch.me/ivanch/mindforge-api:latest ./Mindforge.API $buildArgs Write-Host "Compilando mindforge.cronjob..." docker build -t git.ivanch.me/ivanch/mindforge-cronjob:latest ./mindforge.cronjob $buildArgs } } else { # --- Modo remoto (Docker CLI ausente localmente) --- Write-Host "Docker CLI nao encontrado localmente." -ForegroundColor Yellow if (Test-SshConnection $remoteHost) { Write-Host "Conectando ao host remoto $remoteHost para build..." Invoke-RemoteBuild } else { Write-Error "Docker nao encontrado localmente e host remoto $remoteHost inacessivel. Instale o Docker ou verifique a conectividade SSH." exit 1 } } Write-Host "Compilacao concluida com sucesso." -ForegroundColor Green