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]>
10 KiB
name: coolify-deploy description: Deploy new projects to the local self-hosted Coolify instance from end to end. Use when the user wants to take a local project (or a new idea) and ship it to Coolify: scaffold a compliant Dockerfile/compose, create a GitHub repo, push, register the app in Coolify, deploy it, and verify. Also covers rollback to a previous commit and redeploys. Distinct from coolify-agent (which operates already-deployed apps) and the proxmox-agent (host operations).
Coolify Deploy Skill
Use this skill to take a project from "local code" to "live on
https://<name>.urieljareth.org". It wraps the existing repo tooling
(Proxmox SSH, Coolify API, Cloudflare API) plus new GitHub scaffolding into a
single end-to-end pipeline.
⚠️ Instance reality check (READ FIRST — verified 2026-07 on coolify.urieljareth.org, v4.1.2)
This instance's REST API is partial: the entire /applications/* namespace is
404 (create public/dockerfile/private-*, list, get, PATCH, /envs, /logs).
POST /services only takes raw compose (no git repo). Consequences:
- You cannot create OR configure a git-based build-from-source app via the API here.
New-CoolifyApplication.ps1(POST /applications/public) will 404. - To configure an app that builds from a (private) git repo — set its build pack to
Docker Compose, its compose location, its env vars, and its per-service domains —
you MUST drive the web UI with Playwright. Use
scripts/coolify-ui/*.mjs(needsCOOLIFY_EMAIL/COOLIFY_PASSWORDin.env.local.ps1). - What DOES work via API:
/resources(inventory+status),/projects,/security/keys,/services, andGET /deploy?uuid=&force=true(trigger a deploy of any existing app),GET /deployments/{uuid}(status+logs).
Full playbook + gotchas (UTF-8 BOM breaks Coolify's YAML parser, "Reload Compose File" is
mandatory, don't queue concurrent deploys, PowerShell ReadAllText for key payloads, etc.):
references/coolify-4.1.2-notes.md. Re-verify the API
surface with GET /version if the instance was upgraded.
When to use
- "Deploy this project to Coolify"
- "Create a new GitHub repo and ship it to Coolify"
- "Roll back the Coolify app to yesterday's commit"
- "Generate a Dockerfile that works on this Coolify instance"
- "Validate my repo against the Coolify hard rules before pushing"
When NOT to use
- Operating an already-deployed app (logs, restart, env edits) → use
coolify_skill/SKILL.mdinstead. - Proxmox host or LXC maintenance → use
agent/SKILL.md. - Editing Cloudflare tunnel routes → dashboard-managed, see
docs/runbooks/cloudflare-tunnel.md.
Prerequisites (one-time setup)
.env.local.ps1must contain at minimumCOOLIFY_TOKENandGITHUB_TOKEN. Seereferences/templates/env.local.template.ps1.GITHUB_TOKENis a GitHub PAT (classic withreposcope, or fine-grained withContents: Read+Write+Metadata: Read). Generate at https://github.com/settings/tokens.git pushto GitHub uses Windows Credential Manager (wincred) — no need to embed the PAT in the git URL. The PAT is only for GitHub REST API calls (creating repos, listing).- The authenticated GitHub account is
urieljarethbusiness-cpu(verified viagit credential fill). Override withGITHUB_OWNERif needed. - Operational verification needs Node + Playwright. Run
npm installonce in the manager repo root (H:\MegaSync\Proyectos\Proxmox & Coolify Manager). Chromium binaries cache at%LOCALAPPDATA%\ms-playwright. If Node is missing,Test-ServiceOnline.ps1falls back to curl-only (browser layer is skipped, not failed).
Pipeline
There are two pipelines, one per deploy strategy. Pick based on whether your project ships as a single Dockerfile-built app or as a multi-container Docker Compose stack.
A. Single-app (Dockerfile) — Publish-ProjectToCoolify.ps1
local project
→ Initialize-CoolifyProject.ps1 (optional: scaffold Dockerfile/compose)
→ Test-PreDeployChecklist.ps1 (gate; enforces AGENTS-coolify-apps.md)
→ New-GitHubRepo.ps1 (create repo, idempotent)
→ git push origin main (uses wincred, not the PAT)
→ New-CoolifyApplication.ps1 (project + env + app + envs + deploy)
→ Test-PostDeploy.ps1 (Coolify state: containers, proxy logs, sibling DNS)
→ Test-ServiceOnline.ps1 (OPERATIONAL: HTTP 200 + Playwright page render)
Use Publish-ProjectToCoolify.ps1 to run all seven steps in sequence with one
confirmation per step.
B. Multi-container stack (Docker Compose) — New-CoolifyService.ps1
For projects that ship a docker-compose.coolify.yml (app + sibling DB +
optional sidecars). Reads the local compose file and POSTs it to Coolify's
/services endpoint — the modern replacement for the deprecated
/applications/dockercompose.
local project (with docker-compose.coolify.yml)
→ Test-PreDeployChecklist.ps1 (gate; enforces AGENTS-coolify-apps.md)
→ New-GitHubRepo.ps1 + git push (only if the repo isn't already on GitHub)
→ New-CoolifyService.ps1 (project + env + service + urls + envs + deploy)
→ Test-PostDeploy.ps1 (Coolify state: containers, proxy logs, sibling DNS)
→ Test-ServiceOnline.ps1 (OPERATIONAL: HTTP 200 + Playwright page render)
The compose MUST satisfy the hard rules (no published 80/443, DB by service
name, SERVICE_FQDN_<svc>_<port> placeholders so Coolify wires routes, named
volumes, healthchecks). The urls payload in New-CoolifyService.ps1 maps
one service (e.g. web) to the primary FQDN; pass -ExtraUrls for
multi-public-service stacks.
The final step (Test-ServiceOnline.ps1) is the definition of done for
both pipelines: the service is only considered live when (a) the FQDN returns
HTTP 2xx via curl and (b) a real Chromium browser loads the page with no
uncaught JS errors. It retries for ~80 seconds to allow Traefik/TLS warm-up.
For rollback: Invoke-CoolifyRollback.ps1 pushes the chosen commit to a
rollback/<sha> branch (main stays untouched), repoints the Coolify app, and
redeploys.
Hard rules (must hold for every app)
Read docs/AGENTS-coolify-apps.md for the
canonical version. Summary:
- Sibling DB by service name, never
localhost. - External
coolifynetwork if the app needs shared Coolify services. - Never publish host ports
80/443— Traefik owns them. - FQDN =
https://<name>.urieljareth.orgset before first deploy. TLS via DNS challenge, not HTTP-01. - Secrets as env vars only, never committed or baked.
- Healthcheck on a DB-independent endpoint.
- Named volumes for data that must survive redeploys.
Test-PreDeployChecklist.ps1 enforces these automatically.
Safety policy
- Read-only by default. The first run of any deploy flow only inspects.
- Confirm before mutating. Each step that creates a repo, pushes commits,
creates a Coolify resource, or triggers a deploy asks for confirmation
unless
-Forceis supplied. - Never write secrets into the repo. Tokens live in
.env.local.ps1(gitignored). The skill scripts accept env files but never echo their values. - No force-push to main during rollback. The rollback branch carries the target SHA; main is only moved if the operator does it explicitly.
- State the rollback path before any risky change.
Tooling
See TOOLS.md for the command reference. The scripts in
deploy_skill/scripts/ reuse:
scripts/Invoke-ProxmoxSsh.ps1for any LXC 102 / Docker inspection.coolify_skill/scripts/Invoke-CoolifyApi.ps1for all Coolify API calls.scripts/Invoke-CloudflareApi.ps1if the user asks to add a tunnel route (rare; tunnel is dashboard-managed).
Reference docs
docs/AGENTS-coolify-apps.md— the compatibility contract every project must satisfy. Read before scaffolding.docs/proxmox-inventory.md— verified topology.docs/runbooks/coolify-docker.md— Docker operations inside LXC 102.coolify_skill/references/ops/— per-endpoint Coolify API reference. Search withrg, do not load all.references/templates/— Dockerfile/compose/env templates that already satisfy the hard rules.
Common workflows
1. New project, full pipeline
. .\.env.local.ps1
.\deploy_skill\scripts\Publish-ProjectToCoolify.ps1 `
-AppPath .\my-new-app `
-AppName my-new-app `
-Fqdn https://my-new-app.urieljareth.org `
-Stack node -AppPort 8080 -Init
2. Existing local repo, just register + deploy
.\deploy_skill\scripts\Publish-ProjectToCoolify.ps1 `
-AppPath .\existing-app `
-AppName existing-app `
-Fqdn https://existing-app.urieljareth.org `
-AppPort 3000
2b. Multi-container stack (Docker Compose) — register + deploy
.\deploy_skill\scripts\New-CoolifyService.ps1 `
-AppPath .\my-stack `
-AppName my-stack `
-ComposeFile docker-compose.coolify.yml `
-Fqdn https://my-stack.urieljareth.org `
-PrimaryService web `
-EnvFile .\my-stack\.env.coolify `
-InstantDeploy
3. Rollback to a previous commit
.\deploy_skill\scripts\Invoke-CoolifyRollback.ps1 `
-AppPath .\my-app `
-ApplicationUuid og88wk4 `
-CommitSha a1b2c3d
4. Only validate, no deploy
.\deploy_skill\scripts\Test-PreDeployChecklist.ps1 -Path .\my-app -ExpectedPort 8080 -Strict
5. Verify an already-deployed service is truly live (HTTP 200 + browser)
.\deploy_skill\scripts\Test-ServiceOnline.ps1 `
-Fqdn https://my-app.urieljareth.org `
-ExpectTitle "My App" -Retries 8
This is the operational gate — the answer to "did the deploy actually ship a working page?". Use it after any redeploy, env change, or rollback. It captures a PNG screenshot as evidence.