# =========================================================================== # Deploy-SoloLeveling.ps1 # Re-deploy de "El Sistema (Solo Leveling)" en Coolify (LXC 102) SIN depender # del pull de GHCR (que es privado y sin token read:packages). # # Estrategia: construye la imagen DIRECTO en el server (clone del repo privado # con el PAT scope=repo + docker build), la taguea como ghcr.io/.../solo-leveling:latest # (el nombre que espera el compose generado por Coolify) y levanta el servicio. # Como el compose NO declara pull_policy, docker compose up usa la imagen local. # # Pre-requisitos: # - .env.local.ps1 con COOLIFY_*, PROXMOX_* y GITHUB_TOKEN (scope repo). # - El service ya registrado en Coolify (compose + .env + dominio en su dir). # # Uso: # . .\.env.local.ps1 # .\Deploy-SoloLeveling.ps1 # build + up + verificar # .\Deploy-SoloLeveling.ps1 -NoBuild # solo up + verificar (imagen ya existe) # =========================================================================== [CmdletBinding()] param( [string]$ServiceUuid = 'urm8m4u0jvjggmgpfxblnqwc', [string]$Domain = 'sl.urieljareth.org', [string]$Repo = 'urieljarethbusiness-cpu/solo-leveling', [string]$Image = 'ghcr.io/urieljarethbusiness-cpu/solo-leveling:latest', [switch]$NoBuild ) Set-Location 'H:\MegaSync\Proyectos\Proxmox & Coolify Manager' . .\.env.local.ps1 $ErrorActionPreference = 'Stop' if (-not $env:GITHUB_TOKEN) { throw "GITHUB_TOKEN falta en .env.local.ps1" } # --- helper: ejecuta un .sh (string) dentro del LXC 102 via base64 (sin quote hell) --- function Invoke-OnServer([string]$scriptBody, [int]$TimeoutSec = 600) { $body = ($scriptBody -replace "`r`n","`n") -replace "`r","`n" $b64 = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($body)) $cmd = "pct exec 102 -- sh -c 'echo $b64 | base64 -d | sh'" & .\scripts\Invoke-ProxmoxSsh.ps1 -Command $cmd } # ---------------------------------------------------------------- 1. BUILD --- if (-not $NoBuild) { Write-Host "==> Construyendo imagen en el server (clone + docker build)..." -ForegroundColor Cyan $build = @" set -e BUILD_DIR=/tmp/solo-build rm -rf `"`$BUILD_DIR`" `"/tmp/solo-build.log`" mkdir -p `"`$BUILD_DIR`"; cd `"`$BUILD_DIR`" git clone --depth 1 https://x-access-token:$($env:GITHUB_TOKEN)@github.com/$Repo.git repo cd repo echo "HEAD: `$(git log -1 --oneline)" docker build -t $Image . echo "=== BUILT ===" docker images $Image --format '{{.Repository}}:{{.Tag}} {{.ID}} {{.Size}}' "@ Invoke-OnServer $build } # --------------------------------------------- 2. UP + CONECTAR PROXY --- Write-Host "==> Levantando servicio y conectando proxy Traefik..." -ForegroundColor Cyan $up = @" set +e SVC=/data/coolify/services/$ServiceUuid cd "`$SVC" || { echo "NO_SVC_DIR"; exit 1; } docker compose up -d docker network connect $ServiceUuid coolify-proxy 2>&1 && echo "PROXY_CONNECTED" || echo "(proxy ya conectado)" "@ Invoke-OnServer $up # -------------------------------------------------- 3. ESPERAR + VERIFICAR --- Write-Host "==> Esperando salud (migrate/seed + arranque Next)..." -ForegroundColor Cyan Start-Sleep -Seconds 25 $verify = @" set +e echo "=== STATUS ===" docker compose -f /data/coolify/services/$ServiceUuid/docker-compose.yml ps --format '{{.Name}} | {{.Status}}' echo "=== HEALTH (local) ===" docker exec app-$ServiceUuid wget -qO- http://127.0.0.1:3000/api/health 2>&1 echo "" "@ Invoke-OnServer $verify Write-Host "=== HEALTH (publico: https://$Domain) ===" -ForegroundColor Cyan $code = & curl.exe -s -o NUL -w "%{http_code}" --max-time 30 "https://$Domain/api/health" Write-Host ("PUBLIC_HEALTH=" + $code) if ($code -eq '200') { Write-Host "OK: sitio activo en https://$Domain" -ForegroundColor Green } else { Write-Host "AVISO: health publico no es 200 ($code). Revisar logs: docker logs app-$ServiceUuid" -ForegroundColor Yellow }