5.0 KiB
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)
-
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 enenvironment_variablesde toda la instancia. -
Deploy git+railpack (intento 1):
POST /deploycontra 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, sinindex.htmlen raíz) y railpack eligió un plan "estático con Caddy" que no corresponde. -
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 rechazabuild_pack=dockerimageen 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_buildpackusadocker_registry_image_name, nostatic_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.
- API:
-
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).
-
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 fijardocker_registry_image_taga 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=dockerimageaunque el backend lo soporta yPOST /applications/dockerimagelo crea así. Para convertir una app existente: DB o recrear el recurso. static_imageNO es la imagen del build pack dockerimage — ese modo leedocker_registry_image_name(+docker_registry_image_tag, defaultlatest).- 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_MODEen su preflight (exit 1 si falta) y recomiendaALLOWED_HOSTdetrás de proxy.