Files
Proxmox-Coolify-Manager/deploy_skill/SKILL.md
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

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 (needs COOLIFY_EMAIL/COOLIFY_PASSWORD in .env.local.ps1).
  • What DOES work via API: /resources (inventory+status), /projects, /security/keys, /services, and GET /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.md instead.
  • 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)

  1. .env.local.ps1 must contain at minimum COOLIFY_TOKEN and GITHUB_TOKEN. See references/templates/env.local.template.ps1.
  2. GITHUB_TOKEN is a GitHub PAT (classic with repo scope, or fine-grained with Contents: Read+Write + Metadata: Read). Generate at https://github.com/settings/tokens.
  3. git push to 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).
  4. The authenticated GitHub account is urieljarethbusiness-cpu (verified via git credential fill). Override with GITHUB_OWNER if needed.
  5. Operational verification needs Node + Playwright. Run npm install once in the manager repo root (H:\MegaSync\Proyectos\Proxmox & Coolify Manager). Chromium binaries cache at %LOCALAPPDATA%\ms-playwright. If Node is missing, Test-ServiceOnline.ps1 falls 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:

  1. Sibling DB by service name, never localhost.
  2. External coolify network if the app needs shared Coolify services.
  3. Never publish host ports 80/443 — Traefik owns them.
  4. FQDN = https://<name>.urieljareth.org set before first deploy. TLS via DNS challenge, not HTTP-01.
  5. Secrets as env vars only, never committed or baked.
  6. Healthcheck on a DB-independent endpoint.
  7. 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 -Force is 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.ps1 for any LXC 102 / Docker inspection.
  • coolify_skill/scripts/Invoke-CoolifyApi.ps1 for all Coolify API calls.
  • scripts/Invoke-CloudflareApi.ps1 if the user asks to add a tunnel route (rare; tunnel is dashboard-managed).

Reference docs

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.