# =========================================================================== # Deploy-OhDaddy.ps1 # Redeploy de oh-daddy (https://github.com/KenKaiii/oh-daddy) en Coolify # (LXC 102) SIN depender del pull de Coolify (la imagen es local: # oh-daddy-app:local, construida en el server - patron Deploy-SoloLeveling). # # Stack: app (Next.js 16) + db (postgres:17) + inngest (self-hosted v1.44.0) # + inngest-db + inngest-redis. Servicio Coolify rzittzudkunwx8gilonn7tqe, # proyecto "AI AGENCY" / production. Dominio: ohdaddy.urieljareth.org. # # Pre-requisitos: # - .env.local.ps1 con COOLIFY_*, PROXMOX_* (los secretos OH_DADDY_* solo # se necesitan si vas a re-aplicar envs; el deploy los lee del .env del # servicio en disco). # - stacks/oh-daddy/{Dockerfile,.dockerignore} en este repo (se inyectan # al clone via base64). # # Uso: # . .\.env.local.ps1 # .\scripts\apps\Deploy-OhDaddy.ps1 # build + up + schema + registro # .\scripts\apps\Deploy-OhDaddy.ps1 -NoBuild # solo up + verificaciones # =========================================================================== [CmdletBinding()] param( [string]$ServiceUuid = 'rzittzudkunwx8gilonn7tqe', [string]$Fqdn = 'https://ohdaddy.urieljareth.org', [string]$Repo = 'https://github.com/KenKaiii/oh-daddy.git', [string]$Image = 'oh-daddy-app:local', [switch]$NoBuild ) Set-Location 'H:\MegaSync\Proyectos\Proxmox & Coolify Manager' . .\.env.local.ps1 $ErrorActionPreference = 'Stop' 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 } $stackDir = 'H:\MegaSync\Proyectos\Proxmox & Coolify Manager\stacks\oh-daddy' # ---------------------------------------------------------------- 1. BUILD --- if (-not $NoBuild) { Write-Host "==> Construyendo imagen en el server (clone + docker build)..." -ForegroundColor Cyan $dfB64 = [Convert]::ToBase64String([IO.File]::ReadAllBytes((Join-Path $stackDir 'Dockerfile'))) $diB64 = [Convert]::ToBase64String([IO.File]::ReadAllBytes((Join-Path $stackDir '.dockerignore'))) $build = @" set -e BUILD=/tmp/oh-daddy-build rm -rf "`$BUILD" /tmp/oh-daddy-build.log mkdir -p "`$BUILD"; cd "`$BUILD" git clone --depth 1 $Repo repo cd repo echo "HEAD: `$(git log -1 --oneline)" echo '$dfB64' | base64 -d > Dockerfile echo '$diB64' | base64 -d > .dockerignore nohup sh -c 'cd /tmp/oh-daddy-build/repo && docker build --build-arg NEXT_PUBLIC_APP_URL=$Fqdn -t $Image . ; echo BUILD_EXIT=`$?' > /tmp/oh-daddy-build.log 2>&1 & echo BUILD_STARTED "@ Invoke-OnServer $build Write-Host " (build en background; log: pct exec 102 -- tail -f /tmp/oh-daddy-build.log)" -ForegroundColor DarkGray Write-Host "==> Esperando build (poll cada 30s, max 15min)..." -ForegroundColor Cyan $deadline = (Get-Date).AddMinutes(15) while ((Get-Date) -lt $deadline) { Start-Sleep -Seconds 30 $st = Invoke-OnServer "set +e`ntail -3 /tmp/oh-daddy-build.log`ndocker images $Image --format '{{.ID}}'" if ($st -match 'BUILD_EXIT=0') { Write-Host "OK: imagen $Image construida." -ForegroundColor Green; break } if ($st -match 'BUILD_EXIT=([1-9][0-9]*)') { throw "Build fallo (exit $($Matches[1])). Log: /tmp/oh-daddy-build.log" } Write-Host " ... compilando" -ForegroundColor DarkGray } if (-not $st) { throw "No se pudo confirmar el build." } } # -------------------------------------------------- 2. UP + PROXY + SCHEMA --- Write-Host "==> Levantando stack, conectando proxy y aplicando schema..." -ForegroundColor Cyan $up = @" set -e SVC=/data/coolify/services/$ServiceUuid cd "`$SVC" docker compose up -d docker network connect $ServiceUuid coolify-proxy 2>&1 && echo PROXY_CONNECTED || echo "(proxy ya conectado)" echo "=== SCHEMA (idempotente) ===" docker exec -i db-$ServiceUuid psql -U ohdaddy -d ohdaddy < /tmp/oh-daddy-build/repo/db/schema.sql 2>&1 | grep -cE 'ERROR' | sed 's/^/errores_sql=/' || true echo "=== PS ===" sleep 15 docker compose ps --format '{{.Name}} | {{.Status}}' "@ Invoke-OnServer $up # ------------------------------------------- 3. REGISTRO INNGEST + SALUD --- Write-Host "==> Re-registrando funciones en Inngest (PUT publico)..." -ForegroundColor Cyan $code = & curl.exe -s -o NUL -w "%{http_code}" --max-time 60 -X PUT "$Fqdn/api/inngest" Write-Host ("INNGEST_REGISTER=" + $code) if ($code -ne '200') { Write-Host "AVISO: registro no confirmado. Reintentar cuando la app este healthy: curl -X PUT $Fqdn/api/inngest" -ForegroundColor Yellow } Write-Host "=== HEALTH publico: $Fqdn ===" -ForegroundColor Cyan $code2 = & curl.exe -s -o NUL -w "%{http_code}" --max-time 30 "$Fqdn/login" Write-Host ("PUBLIC_LOGIN=" + $code2) if ($code2 -eq '200') { Write-Host "OK: oh-daddy activo en $Fqdn" -ForegroundColor Green } else { Write-Host "AVISO: /login no responde 200 ($code2). Logs: docker logs app-$ServiceUuid" -ForegroundColor Yellow }