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]>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
cd998ce6b0
commit
e7d1c33cd5
@@ -0,0 +1,112 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Initialize a project directory for compliant Coolify deployment.
|
||||
|
||||
.DESCRIPTION
|
||||
Copies the right template (Node / Python / multi-container) into the target
|
||||
project: Dockerfile, docker-compose, .dockerignore, plus a Coolify env
|
||||
template. Idempotent: never overwrites existing files unless -Force.
|
||||
|
||||
.PARAMETER Path
|
||||
Target project directory. Defaults to current directory.
|
||||
|
||||
.PARAMETER Stack
|
||||
Which template to scaffold. One of: node, python, compose, static.
|
||||
|
||||
.PARAMETER AppPort
|
||||
Listening port to bake into the Dockerfile and compose. Default 8080.
|
||||
|
||||
.PARAMETER Force
|
||||
Overwrite existing Dockerfile / docker-compose / .dockerignore.
|
||||
|
||||
.EXAMPLE
|
||||
.\Initialize-CoolifyProject.ps1 -Path .\my-app -Stack node -AppPort 8080
|
||||
#>
|
||||
param(
|
||||
[string]$Path = ".",
|
||||
|
||||
[ValidateSet("node", "python", "compose", "static")]
|
||||
[string]$Stack = "node",
|
||||
|
||||
[int]$AppPort = 8080,
|
||||
|
||||
[switch]$Force
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
$templates = Join-Path $here "..\references\templates"
|
||||
$target = (Resolve-Path -LiteralPath $Path).Path
|
||||
|
||||
function Copy-Template {
|
||||
param([string]$Source, [string]$Dest)
|
||||
if (-not (Test-Path -LiteralPath $Source)) { throw "Template not found: $Source" }
|
||||
if ((Test-Path -LiteralPath $Dest) -and -not $Force) {
|
||||
Write-Host " skip (exists): $Dest" -ForegroundColor Yellow
|
||||
return
|
||||
}
|
||||
Copy-Item -LiteralPath $Source -Destination $Dest -Force:$Force
|
||||
Write-Host " wrote: $Dest" -ForegroundColor Green
|
||||
}
|
||||
|
||||
Write-Host "Initializing $target with stack=$Stack port=$AppPort" -ForegroundColor Cyan
|
||||
|
||||
switch ($Stack) {
|
||||
"node" {
|
||||
Copy-Template (Join-Path $templates "Dockerfile.node") (Join-Path $target "Dockerfile")
|
||||
}
|
||||
"python" {
|
||||
Copy-Template (Join-Path $templates "Dockerfile.python") (Join-Path $target "Dockerfile")
|
||||
}
|
||||
"compose" {
|
||||
Copy-Template (Join-Path $templates "Dockerfile.node") (Join-Path $target "Dockerfile")
|
||||
Copy-Template (Join-Path $templates "docker-compose.app-db.yml") (Join-Path $target "docker-compose.yml")
|
||||
}
|
||||
"static" {
|
||||
# Static sites are served by nginx in Coolify; no Dockerfile required.
|
||||
Write-Host " (static stack: no Dockerfile needed; Coolify uses is_static + static_image)" -ForegroundColor DarkGray
|
||||
}
|
||||
}
|
||||
|
||||
# .dockerignore (idempotent)
|
||||
$di = Join-Path $target ".dockerignore"
|
||||
if ((-not (Test-Path -LiteralPath $di)) -or $Force) {
|
||||
@(
|
||||
".git",
|
||||
".gitignore",
|
||||
".env*",
|
||||
"node_modules",
|
||||
"vendor",
|
||||
"__pycache__",
|
||||
"*.log",
|
||||
".vscode",
|
||||
".idea",
|
||||
"README.md"
|
||||
) | Set-Content -LiteralPath $di -Encoding utf8
|
||||
Write-Host " wrote: $di" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host " skip (exists): $di" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
# Recommended .gitignore additions (idempotent, append-only if missing)
|
||||
$gi = Join-Path $target ".gitignore"
|
||||
$existing = if (Test-Path -LiteralPath $gi) { Get-Content -LiteralPath $gi } else { @() }
|
||||
$additions = @(".env", ".env.local", ".env.*.local", "*.key", "*.pem") | Where-Object { $_ -notin $existing }
|
||||
if ($additions) {
|
||||
if (-not (Test-Path -LiteralPath $gi)) { "" | Set-Content -LiteralPath $gi -Encoding utf8 }
|
||||
Add-Content -LiteralPath $gi -Value "`n# Added by deploy_skill"
|
||||
$additions | ForEach-Object { Add-Content -LiteralPath $gi -Value $_ }
|
||||
Write-Host " updated: $gi (+$($additions.Count) lines)" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host " skip (already covered): $gi" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
Write-Host "`nNext steps:" -ForegroundColor Cyan
|
||||
Write-Host " 1. Implement /health in your app (DB-independent, returns 200)."
|
||||
Write-Host " 2. Put real secrets in a local .env.coolify file (not committed)."
|
||||
Write-Host " 3. Run Test-PreDeployChecklist.ps1 to validate."
|
||||
Write-Host " 4. Run New-GitHubRepo.ps1 to create the repo."
|
||||
Write-Host " 5. git push -u origin main."
|
||||
Write-Host " 6. Run New-CoolifyApplication.ps1 to register and deploy."
|
||||
Write-Host " 7. Run Test-PostDeploy.ps1 to verify."
|
||||
Reference in New Issue
Block a user