Files
Proxmox-Coolify-Manager/deploy_skill/scripts/Initialize-CoolifyProject.ps1
T
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

113 lines
4.0 KiB
PowerShell

<#
.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."