Files
Proxmox-Coolify-Manager/docs/casos/open-seo-gestion-desde-coolify.md
T

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)

  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.