fix(tpv-dev-in-prod): tPV production is running next dev (HMR + React DevTools visible)
This commit is contained in:
@@ -138,7 +138,7 @@ cd project
|
||||
./scripts/monolith.sh prod start
|
||||
```
|
||||
|
||||
Usa `npm ci`, aplica migraciones, construye backend/admin/frontend/storefront y arranca todo en `0.0.0.0`.
|
||||
Usa `npm ci`, aplica migraciones, construye backend/admin/frontend/storefront y arranca todo en `0.0.0.0`. Al finalizar ejecuta un **smoke test post-arranque** que verifica que ninguno de los servicios Next está sirviendo modo dev (sin HMR, sin `react-refresh`, sin banner `(Turbopack)`). Si detecta un dev server activo, aborta el arranque con un mensaje claro.
|
||||
|
||||
### Redeploy / reinicio completo
|
||||
|
||||
@@ -149,6 +149,51 @@ cd project
|
||||
|
||||
Detiene únicamente PIDs registrados en `.runtime/prod/`; nunca usa `pkill` global. Si un puerto está ocupado por un proceso ajeno, falla y muestra el PID.
|
||||
|
||||
### 3.1 Errores comunes — jamás arranques `dev` en un host de producción
|
||||
|
||||
**Regla de oro:** en cualquier host expuesto al público (sea LAN, VPS o servidor de tienda), usa **siempre** `./scripts/monolith.sh prod`. El modo `dev` está reservado para desarrollo local en `127.0.0.1`.
|
||||
|
||||
#### Por qué `next dev` no es un atajo válido en producción
|
||||
|
||||
- **Expone internals:** el bundle del cliente incluye `react-refresh`, `__webpack_require__`, el cliente HMR y los mensajes "Download the React DevTools". Cualquier visitante ve el código fuente sin minificar.
|
||||
- **Hackeable:** el endpoint `/_next/hmr` queda abierto y acepta WebSocket upgrades. Esto filtra nombres de archivos del servidor, permite lecturas no autenticadas del árbol de fuentes y rompe asunciones de seguridad (CSP, cookies Secure, CORS).
|
||||
- **Rota el PWA:** Chrome exige un `manifest.webmanifest` válido. `next dev` no genera el manifest correctamente en algunos setups y dispara errores CORS cuando un auth-proxy (Authelia) intenta proteger la ruta.
|
||||
- **Rendimiento ~10× peor:** Turbopack compila cada request bajo demanda y mantiene cachés en memoria que pueden llegar a GB. Sin monitorización, esto degrada el TPV hasta hacerlo inutilizable en horas punta.
|
||||
- **Rompe el ciclo de release:** los artefactos `.next/` de dev no son válidos para `next start`. Si mezclas `dev` y `start` en el mismo árbol, los reinicios de prod fallan silenciosamente porque los PIDs no se registran.
|
||||
|
||||
#### Señales de que estás corriendo `dev` por accidente
|
||||
|
||||
- El log del servicio dice `▲ Next.js 16.3.1 (Turbopack)` — la coletilla `(Turbopack)` solo aparece en `next dev`.
|
||||
- La consola del navegador muestra intentos de WebSocket a `/_next/hmr` y mensajes `[HMR] connected` repetidos.
|
||||
- Verás `Download the React DevTools` al cargar cualquier página.
|
||||
- `lsof -nP -iTCP:3002 -sTCP:LISTEN` muestra un PID de `node .../next/dist/bin/next dev` en lugar de `next start`.
|
||||
|
||||
#### Runbook de recuperación rápida (si ya estás sirviendo dev en prod)
|
||||
|
||||
```bash
|
||||
# 1) Identificar el proceso dev en :3002 (TPV) y :3001 (admin)
|
||||
lsof -nP -iTCP:3002 -sTCP:LISTEN
|
||||
lsof -nP -iTCP:3001 -sTCP:LISTEN
|
||||
|
||||
# 2) Detenerlo (sustituye <PID> por el del paso anterior)
|
||||
kill -TERM <PID>
|
||||
|
||||
# 3) Confirmar que el puerto queda libre
|
||||
lsof -nP -iTCP:3002 -sTCP:LISTEN # debe devolver nada
|
||||
|
||||
# 4) Limpiar runtime stale (incluye dev huérfano)
|
||||
rm -f project/.runtime/dev/*.pid
|
||||
|
||||
# 5) Arrancar prod (con smoke test post-arranque)
|
||||
cd project && ./scripts/monolith.sh prod start
|
||||
|
||||
# 6) Confirmar: el log dirá "▲ Next.js 16.3.1" SIN "(Turbopack)"
|
||||
tail project/.runtime/prod/tpv.log
|
||||
# debe terminar con la línea de Ready y NADA de WebSocket /_next/hmr
|
||||
```
|
||||
|
||||
Si el smoke test falla igualmente, abre un ticket: hay otro proceso (posiblemente externo al script) ocupando el puerto y `monolith.sh` no puede broad-kill por seguridad.
|
||||
|
||||
### Estado, logs y stop
|
||||
|
||||
```bash
|
||||
@@ -279,6 +324,22 @@ curl -fsS -o /dev/null http://127.0.0.1:3004/
|
||||
curl -fsS -o /dev/null http://127.0.0.1:3005/
|
||||
```
|
||||
|
||||
Comprobaciones adicionales anti-dev (TPV-DEV-IN-PROD):
|
||||
|
||||
```bash
|
||||
# 1) El log del TPV NO debe contener "(Turbopack)"
|
||||
! grep -F '(Turbopack)' project/.runtime/prod/tpv.log
|
||||
|
||||
# 2) /_next/hmr debe devolver 404 o 426 (no 200/101/405)
|
||||
code=$(curl -sS -o /dev/null -w '%{http_code}' http://127.0.0.1:3002/_next/hmr)
|
||||
[[ "$code" == "404" || "$code" == "426" ]]
|
||||
|
||||
# 3) El HTML inicial NO debe contener marcadores de dev
|
||||
! curl -fsS http://127.0.0.1:3002/ | grep -qE '/__next_hmr|react-refresh|Download the React DevTools'
|
||||
```
|
||||
|
||||
Repetir para `:3001` (admin), `:3003` (frontend) y `:3004` (storefront) si también están en producción. Si cualquiera falla, sigue el runbook de §3.1 antes de continuar.
|
||||
|
||||
---
|
||||
|
||||
## 7. Problemas frecuentes
|
||||
|
||||
@@ -65,6 +65,8 @@ npm run build
|
||||
|
||||
The monolith script handles each app independently; a single `restart` rebuilds and respawns all services.
|
||||
|
||||
> ⚠️ **Nunca** ejecutes `npm run dev` ni `./scripts/monolith.sh dev` en el host público del TPV. El modo dev expone HMR, React DevTools y endpoints internos a cualquier visitante, y rompe la PWA (manifest y cookies Secure). Para producción usa exclusivamente `prod`; tras el arranque, `monolith.sh` ejecuta un smoke test que falla ruidosamente si detecta un dev server activo. Detalles y runbook de recuperación en `docs/HOWTO-monolith.md` §3.1.
|
||||
|
||||
---
|
||||
|
||||
## 2. Daily operations
|
||||
|
||||
Reference in New Issue
Block a user