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

234 lines
10 KiB
Markdown

---
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`](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`](../coolify_skill/SKILL.md) instead.
- Proxmox host or LXC maintenance → use [`agent/SKILL.md`](../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`](../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`](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
- [`docs/AGENTS-coolify-apps.md`](../docs/AGENTS-coolify-apps.md) — the
compatibility contract every project must satisfy. Read before scaffolding.
- [`docs/proxmox-inventory.md`](../docs/proxmox-inventory.md) — verified
topology.
- [`docs/runbooks/coolify-docker.md`](../docs/runbooks/coolify-docker.md) —
Docker operations inside LXC 102.
- [`coolify_skill/references/ops/`](../coolify_skill/references/ops/) —
per-endpoint Coolify API reference. Search with `rg`, do not load all.
- [`references/templates/`](references/templates/) — Dockerfile/compose/env
templates that already satisfy the hard rules.
## Common workflows
### 1. New project, full pipeline
```powershell
. .\.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
```powershell
.\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
```powershell
.\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
```powershell
.\deploy_skill\scripts\Invoke-CoolifyRollback.ps1 `
-AppPath .\my-app `
-ApplicationUuid og88wk4 `
-CommitSha a1b2c3d
```
### 4. Only validate, no deploy
```powershell
.\deploy_skill\scripts\Test-PreDeployChecklist.ps1 -Path .\my-app -ExpectedPort 8080 -Strict
```
### 5. Verify an already-deployed service is truly live (HTTP 200 + browser)
```powershell
.\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.