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,233 @@
|
||||
---
|
||||
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.
|
||||
Reference in New Issue
Block a user