Actualiza toolkit operativo y documentación

This commit is contained in:
urieljareth
2026-09-10 20:53:50 -06:00
parent 3b7209dcc1
commit 714057bfc8
69 changed files with 6023 additions and 384 deletions
@@ -0,0 +1,98 @@
# Caso: open-seo vuelve a gestión completa de Coolify (imagen precompilada)
**Fecha:** 2026-09-04/05 · **App:** `open-seo:main-0fgs5kwaab9esytaxkddsvts`
(uuid `kj0kccsb4d46tm0d6qe6docy`, id DB 57) · **FQDN:**
`https://kj0kccsb4d46tm0d6qe6docy.urieljareth.org`
## Contexto
El sitio público estaba sirviéndose por una **cadena manual improvisada** tras
la caída del 2026-08-27 22:14:
```
Traefik → open-seo-sidecar (nginx:alpine manual, montado 22:25 ese día)
→ proxy_pass → test-openseo (docker run manual de ghcr.io/every-app/open-seo:latest)
```
La aplicación en Coolify quedó `exited:unhealthy` sin contenedor. El usuario
fijó como objetivo: **todo gestionable desde Coolify**.
## Qué se hizo (en orden)
1. **Limpieza de filas huérfanas de env vars** (ids 1152-1156, app 52
`insta-portal`): eran duplicados invisibles de un INSERT SQL manual con el
morph type mal escapado (`App\\Models\\Application`). Las variables reales ya
existían cifradas (ids 1161-1170) → se **borraron** los duplicados, no se
activaron. Backup: `/root/backups/envvar-orphans-1152-1156-20260904-212119.tsv`.
Tras esto: 0 valores sin cifrar en `environment_variables` de toda la instancia.
2. **Deploy git+railpack (intento 1):** `POST /deploy` contra el origen. El
build tardó ~23 min y terminó, pero la app servía **404**: el repo
(`github.com/every-app/open-seo`, público, actualizado ese mismo día) ahora
compila un monorepo (`dist/client|server|open_seo_audit`, sin `index.html`
en raíz) y railpack eligió un plan "estático con Caddy" que no corresponde.
3. **Conversión a imagen precompilada** (doctrina del caso firecrawl):
- API: `docker_registry_image_name=ghcr.io/every-app/open-seo`,
`docker_registry_image_tag=latest` (la API acepta estos campos).
- DB: `UPDATE applications SET build_pack='dockerimage' WHERE id=57` — la
API **rechaza** `build_pack=dockerimage` en PATCH (enum de validación sin
ese valor, 422 "The selected build pack is invalid"), aunque el pipeline
de deploy lo soporta de forma nativa
(`deploy_dockerimage_buildpack` usa `docker_registry_image_name`, no
`static_image`). Backup previo:
`/root/backups/app57-pre-dockerimage-20260904-215456.tsv`.
- Deploy 2: pull de `:latest` + rolling update. El contenedor
**crash-loopeaba (exit 1)**: el preflight de la nueva imagen exige
configurar auth.
4. **Env vars nuevas vía API** (`POST /applications/{uuid}/envs` — cifra por
modelo, sin riesgo del bug de texto plano):
- `AUTH_MODE=local_noauth` — replica el estado previo (el sitio ya corría
público sin auth vía sidecar). Para Cloudflare Access:
`AUTH_MODE=cloudflare_access` + `TEAM_DOMAIN` + `POLICY_AUD`.
- `ALLOWED_HOST=kj0kccsb4d46tm0d6qe6docy.urieljareth.org` — allowlist de
Vite detrás de proxy.
- Deploy 3: contenedor **healthy** (la imagen GHCR trae healthcheck con
`start_period=300s`, a diferencia de los servicios del §1.5 del índice).
5. **Retiro de los contenedores manuales** (con snapshots previos en
`/root/backups/*-inspect-20260904-212317.json`):
- `open-seo-sidecar` (nginx) — además sus labels duplicaban los routers de
Traefik del FQDN y provocaban 503 mientras coexistía con el contenedor nuevo.
- `test-openseo` (backend manual) — ya sin referencias.
## Resultado
```
status=running:healthy
build_pack=dockerimage image=ghcr.io/every-app/open-seo:latest
FQDN → HTTP 200 <title>OpenSEO</title> (servido por el contenedor de Coolify)
```
Dominio, env vars (DATAFORSEO_API_KEY, AUTH_MODE, ALLOWED_HOST), healthcheck,
redeploys y rollbacks: todo administrable desde la UI/API de Coolify.
## Rollback
- **App a git-build:** `UPDATE applications SET build_pack='railpack' WHERE
id=57;` y redeploy (nota: con el main actual vuelve a servir 404 — ver paso 2).
- **Imagen anterior:** el tag local `ghcr.io/every-app/open-seo:sha-c469a48`
(12 días) sigue en el host; o fijar `docker_registry_image_tag` a ese sha.
- **Contenedores manuales:** recrear desde los inspect snapshots (sidecar:
`docker run -d --name open-seo-sidecar --network coolify --restart
unless-stopped -v /tmp/openseo-sidecar/nginx.conf:/etc/nginx/nginx.conf:ro
<labels-del-snapshot> nginx:alpine`).
## Lecciones (añadir a la lista mental de gotchas)
- **PATCH /applications/{uuid} no acepta `build_pack=dockerimage`** aunque el
backend lo soporta y `POST /applications/dockerimage` lo crea así. Para
convertir una app existente: DB o recrear el recurso.
- **`static_image` NO es la imagen del build pack dockerimage** — ese modo lee
`docker_registry_image_name` (+`docker_registry_image_tag`, default `latest`).
- **Un contenedor manual con los labels de Traefik de una app de Coolify
rompe el enrutamiento** cuando la app real vuelve a deployar (routers
duplicados → 503). Al restaurar una app, retirar esos "sidecars con labels".
- La nueva imagen de open-seo exige `AUTH_MODE` en su preflight (exit 1 si
falta) y recomienda `ALLOWED_HOST` detrás de proxy.