deploy: la demo queda en línea en fspm-demo.urieljareth.org

Desplegada y verificada de punta a punta contra el dominio público, en
Chromium y en WebKit a 375px: sitio, catálogo filtrado, acceso al panel,
persistencia de sesión y captura de leads con atribución de campaña.

No quedó como recurso de Coolify, y está documentado por qué: la API de esa
instancia no expone creación de aplicaciones (las rutas /applications/*
responden 404 con cuerpo vacío y /openapi.yaml devuelve el HTML del panel),
y al crear un servicio por /services la tarea de despliegue quedó colgada sin
escribir nada en disco. El servidor está sano; el problema es la instancia.

El contenedor corre en el Docker del LXC 102, en la red coolify, con las
etiquetas de Traefik que replican el patrón de las apps que ya sirven con TLS
ahí, y con coolify.managed=false para que nadie lo confunda con un recurso del
panel. La imagen se construye dentro del LXC desde el repo público de Gitea.

El costo de esta ruta está escrito en la documentación: un push no redespliega.
Se agregó el procedimiento de tres comandos para publicar una versión nueva sin
tocar el volumen, y la vía para migrar a app git-based si se consigue el acceso
al panel web.

Se documenta también una carrera que provocó un diagnóstico equivocado: el
acceso usa una acción de servidor, y pulsar el botón antes de que React hidrate
no hace nada ni da error. La primera verificación fallaba solo por el dominio
público y funcionaba contra Traefik directo, lo que parecía señalar a
Cloudflare. No era: los chunks son idénticos por ambos caminos y la hidratación
es igual. Era la espera de la prueba.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
Uriel Jareth
2026-08-28 10:23:12 -06:00
co-authored by Claude Opus 5
parent 31ee899987
commit 15d31b5d6b
5 changed files with 180 additions and 0 deletions
+69
View File
@@ -3,6 +3,61 @@
Sitio de FSPM con micro CRM. Un solo contenedor: Next.js en modo `standalone` y
SQLite en un volumen. No hay base de datos externa.
## Cómo está desplegado hoy
**En línea:** https://fspm-demo.urieljareth.org
No es un recurso de Coolify, y eso es deliberado. La API de esta instancia no
expone creación de aplicaciones —las tres rutas `/applications/*` responden 404
con cuerpo vacío, y `/openapi.yaml` devuelve el HTML del panel—, y al crear un
servicio por `POST /services` la tarea de despliegue quedó colgada sin escribir
nada en `/data/coolify/services/`. La interfaz web reportaba "No available
server" aunque el servidor está sano (verificado por API: alcanzable, usable,
Traefik corriendo, red `coolify` presente, dominio comodín configurado).
Así que el contenedor corre directamente en el Docker del LXC 102, en la red
`coolify`, con las etiquetas de Traefik que replican el patrón de las
aplicaciones que ya sirven con TLS en ese servidor. Lleva
`coolify.managed=false` para que nadie lo confunda con un recurso del panel.
- Imagen: `fspm-web:demo`, construida **dentro del LXC 102** desde el repo
público de Gitea. No hay registro de contenedores en juego.
- Contenedor: `fspm-web`, con `--restart unless-stopped`, así que sobrevive a
un reinicio del LXC.
- Volumen: `fspm-datos` montado en `/app/data`.
- Certificado: lo emite el Traefik que ya estaba, con `letsencrypt`.
**La consecuencia operativa importante:** un push a Gitea **no** redespliega.
Ver "Publicar una versión nueva" abajo.
### Publicar una versión nueva
Tres comandos desde el host Proxmox (`ssh -i keys/proxmox_ed25519 [email protected]`):
```bash
# 1. traer el código nuevo
pct exec 102 -- git -C /opt/fspm-src pull
# 2. reconstruir la imagen (los NEXT_PUBLIC_* se hornean aquí)
pct exec 102 -- docker build -t fspm-web:demo --build-arg NEXT_PUBLIC_SITE_URL=https://fspm-demo.urieljareth.org --build-arg NEXT_PUBLIC_WHATSAPP=525540348395 /opt/fspm-src
# 3. recrear el contenedor — el volumen NO se toca, los leads se conservan
pct exec 102 -- docker rm -f fspm-web
# y volver a correr `deploy/fspm-live.sh` (lleva el AUTH_SECRET sustituido)
```
El script `deploy/fspm-live.sh` del repo tiene el `docker run` completo con las
etiquetas de Traefik; el `AUTH_SECRET` va como marcador y se sustituye al
ejecutarlo.
### Si algún día se puede usar Coolify
Con el correo del panel web se puede crear la aplicación como **Public
Repository → Dockerfile** apuntando al repo de Gitea, y entonces sí recupera el
redespliegue automático por push. La especificación exacta de campos está en la
sección "Coolify" de abajo. En ese momento hay que **eliminar el contenedor
manual** para que no compitan dos backends por el mismo dominio en Traefik.
## Variables de entorno
| Variable | Requerida | Qué pasa si falta |
@@ -110,6 +165,20 @@ curl -H "Authorization: Bearer $COOLIFY_TOKEN" \
"$COOLIFY_API_URL/deploy?uuid=<uuid de la aplicación>"
```
## Una carrera que confunde: hidratación y latencia
El acceso al panel usa una acción de servidor. Hasta que React no hidrata la
página, pulsar el botón **no hace nada y no da error**. Con poca latencia no se
nota; a través de Cloudflare, sí.
Esto costó un diagnóstico equivocado: la primera verificación automatizada
pulsaba el botón demasiado pronto, fallaba solo por el dominio público y
funcionaba pegándole a Traefik directo, lo que apuntaba a Cloudflare. No era
Cloudflare —los chunks de JavaScript son byte a byte idénticos por los dos
caminos y la hidratación es igual—, era la espera de la prueba. Si alguien
vuelve a ver este síntoma, antes de culpar al proxy conviene esperar `load` más
un margen y volver a medir.
## Verificación posterior al despliegue
Hazla en este orden; cada punto descarta una clase distinta de falla.