Files
urieljarethandClaude Opus 4.8 e7d1c33cd5 deploy_skill: soporte para Coolify v4.1.2 (API /applications 404) + flujo UI Playwright
Aprendido desplegando cotizador (Next.js+FastAPI+Postgres, Docker Compose,
repo privado) en coolify.urieljareth.org (v4.1.2):

- Documenta que /applications/* devuelve 404 en esta instancia y que configurar
  apps git build-from-source solo es posible por la UI web.
- Nuevos scripts scripts/coolify-ui/: coolify-login.mjs (guarda storageState) y
  Configure-CoolifyComposeApp.mjs (build pack -> Docker Compose, Reload Compose
  File, env vars por Developer view, dominios por servicio).
- references/coolify-4.1.2-notes.md: mapa de API funcional/404, gotchas (BOM
  UTF-8 rompe el parser YAML de Coolify; Reload Compose File obligatorio; pin de
  dominios por servicio o 503; no encolar deploys concurrentes; PowerShell
  [IO.File]::ReadAllText para payloads de llaves).
- env.local.template.ps1: COOLIFY_EMAIL/COOLIFY_PASSWORD para la UI.
- SKILL.md/TOOLS.md: seccion "instance reality" y flujo UI paso a paso.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-07-08 00:42:12 -06:00

157 lines
4.9 KiB
PowerShell

<#
.SYNOPSIS
End-to-end deployment pipeline for a project going to this Coolify instance.
.DESCRIPTION
Orchestrates the full flow:
1. Initialize-CoolifyProject (optional, if -Init)
2. Test-PreDeployChecklist (gate; aborts on FAIL)
3. New-GitHubRepo (creates the repo, idempotent)
4. git init/add/commit/push (local repo -> origin)
5. New-CoolifyApplication (project + env + app + envs + deploy)
6. Test-PostDeploy (verification)
All mutating steps ask for explicit confirmation unless -Force is given.
.PARAMETER AppPath
Local path of the project. Defaults to current directory.
.PARAMETER AppName
Name used for the GitHub repo and the Coolify app. Required.
.PARAMETER Fqdn
https://<name>.urieljareth.org. Required.
.PARAMETER Stack
Template to scaffold if -Init: node, python, compose, static.
.PARAMETER AppPort
Internal listening port. Default 8080.
.PARAMETER EnvFile
Optional .env file with KEY=VALUE lines to push into Coolify.
.PARAMETER Branch
Branch to push and deploy. Default: main.
.PARAMETER Init
Scaffolde Dockerfile/compose before pushing (skip if already present).
.PARAMETER Force
Skip per-step confirmation. Use with care.
.EXAMPLE
.\Publish-ProjectToCoolify.ps1 -AppPath .\my-app -AppName my-app `
-Fqdn https://my-app.urieljareth.org -Stack node -AppPort 8080
#>
param(
[string]$AppPath = ".",
[Parameter(Mandatory = $true)]
[ValidatePattern('^[A-Za-z0-9._-]+$')]
[string]$AppName,
[Parameter(Mandatory = $true)]
[string]$Fqdn,
[ValidateSet("node", "python", "compose", "static")]
[string]$Stack = "node",
[int]$AppPort = 8080,
[string]$EnvFile,
[string]$Branch = "main",
[switch]$Init,
[switch]$Force
)
$ErrorActionPreference = "Stop"
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
function Call-Step([string]$Label, [scriptblock]$Block) {
Write-Host "`n>>> $Label`n" -ForegroundColor Magenta
& $Block
if ($LASTEXITCODE -and $LASTEXITCODE -ne 0) { throw "Step failed: $Label (exit $LASTEXITCODE)" }
}
function Confirm-Step([string]$Action) {
if ($Force) { return $true }
$r = Read-Host "Confirm: $Action`nProceed? (y/N)"
return ($r -match '^(y|yes|s|si|sí)$')
}
$appPath = (Resolve-Path -LiteralPath $AppPath).Path
if ($Init) {
Call-Step "1. Scaffold Dockerfile/compose (Initialize-CoolifyProject)" {
& (Join-Path $here "Initialize-CoolifyProject.ps1") -Path $appPath -Stack $Stack -AppPort $AppPort
}
}
Call-Step "2. Pre-deploy checklist (Test-PreDeployChecklist)" {
& (Join-Path $here "Test-PreDeployChecklist.ps1") -Path $appPath -ExpectedPort $AppPort -Strict
}
Call-Step "3. Create GitHub repo (New-GitHubRepo)" {
& (Join-Path $here "New-GitHubRepo.ps1") -Name $AppName -Description "Deployed via coolify-deploy skill"
}
$origin = "https://github.com/urieljarethbusiness-cpu/$AppName.git"
Write-Host "`nOrigin: $origin" -ForegroundColor Cyan
Push-Location -LiteralPath $appPath
try {
if (-not (Test-Path -LiteralPath (Join-Path $appPath ".git"))) {
if (-not (Confirm-Step "git init + add remote origin")) { throw "Aborted." }
git init -b $Branch
git remote add origin $origin
} else {
$existing = git remote get-url origin 2>$null
if ($existing -ne $origin) {
if (-not (Confirm-Step "git remote set-url origin -> $origin")) { throw "Aborted." }
git remote set-url origin $origin
}
}
Call-Step "4. git add / commit / push" {
git add -A
$pending = (git status --porcelain).Count
if ($pending -gt 0) {
if (-not (Confirm-Step "Commit $pending change(s) and push to origin/$Branch")) { throw "Aborted." }
git commit -m "Initial deployment via coolify-deploy skill"
} else {
Write-Host " nothing to commit (clean tree)" -ForegroundColor DarkGray
}
git push -u origin $Branch 2>&1 | ForEach-Object { Write-Host " $_" -ForegroundColor DarkGray }
}
} finally {
Pop-Location
}
Call-Step "5. Create Coolify application + deploy (New-CoolifyApplication)" {
$args = @(
"-RepoUrl", $origin,
"-Branch", $Branch,
"-Fqdn", $Fqdn,
"-PortsExposes", "$AppPort"
)
if ($EnvFile) { $args += @("-EnvFile", $EnvFile) }
if ($Force) { $args += "-Force" }
& (Join-Path $here "New-CoolifyApplication.ps1") @args
}
Call-Step "6. Post-deploy inspection (Test-PostDeploy)" {
& (Join-Path $here "Test-PostDeploy.ps1") -Fqdn $Fqdn -ContainerName "$AppName-main"
}
Call-Step "7. Operational verification: HTTP 200 + Playwright (Test-ServiceOnline)" {
& (Join-Path $here "Test-ServiceOnline.ps1") -Fqdn $Fqdn -Retries 8
}
Write-Host "`n=== Pipeline complete ===" -ForegroundColor Green
Write-Host "App: $Fqdn" -ForegroundColor Cyan
Write-Host "Repo: $origin" -ForegroundColor Cyan