Despliegue en Windows con NSSM en lugar de WinSW

El servicio de Windows pasa a administrarse con NSSM (decisión del usuario: WinSW no se
consideró lo bastante estable).

- instalar-servicio.ps1: recibe -Nssm (ruta de nssm.exe) y configura el servicio con
  `nssm install` / `nssm set` (arranque automático, reinicio a los 10 s, logs a logs\ rotados
  a los 10 MB). Nueva opción -SoloMostrar que imprime los comandos sin ejecutarlos ni exigir
  administrador. Si un ajuste falla, quita el servicio a medio configurar.
- desinstalar-servicio.ps1: usa `nssm stop` y `nssm remove`.
- Se elimina la plantilla XML de WinSW.
- DEPLOY.md: pasos con NSSM, sección para administrar el servicio, aviso de usar la
  compilación 2.24-101 en Windows 10/11 y Server 2019/2022 (la 2.24 estable puede no arrancar),
  y limpieza de logs rotados (NSSM no limita cuántos conserva). Ya no se requiere .NET Framework.
- CLAUDE.md y README de la API actualizados.

Sin probar aún en Windows: solo se comprobó la sintaxis y los comandos generados (-SoloMostrar).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
georgeandClaude Sonnet 5.5 committed 2026-10-13 08:55:29 -05:00
1 parent 287b187c14
commit 699dd983d0
6 files changed
+147 -99

No files matched your search

+49 -16
View File
@@ -1,7 +1,7 @@
# Despliegue en Windows
La aplicación se ejecuta como **un solo servicio de Windows**: la API (NestJS) sirve también la web
compilada (Angular), por HTTPS y en un único puerto. El servicio lo administra **WinSW**.
compilada (Angular), por HTTPS y en un único puerto. El servicio lo administra **NSSM**.
```
Navegador ──HTTPS :443──▶ servicio "DevolucionProveedores" (node dist\main.js)
@@ -15,21 +15,26 @@ memoria de la API, **reiniciar el servicio cierra la sesión de todos los usuari
> **Estado de esta guía.** La carpeta publicada, la API con HTTPS, la web servida por la API, la
> redirección HTTP→HTTPS y los logs sin colores se probaron en un Mac. Los scripts de PowerShell y
> WinSW **no se han ejecutado todavía en Windows** (se comprobó su sintaxis y la generación del XML).
> Tampoco se ha probado contra HANA. Haga la primera instalación en un servidor de pruebas.
> NSSM **no se han ejecutado todavía en Windows** (se comprobó su sintaxis y los comandos de NSSM que
> generan, con `-SoloMostrar`). Tampoco se ha probado contra HANA. Haga la primera instalación en un servidor de pruebas.
## 1. Requisitos del servidor
| Qué | Detalle |
|---|---|
| Windows | Windows Server 2016 o superior. |
| .NET Framework | 4.6.1 o superior (lo necesita WinSW; viene con Windows Server 2016+). |
| Node.js | **22 LTS** o superior, instalado para todos los usuarios (`node -v` en una consola nueva). |
| Red | Acceso al Service Layer de SAP (puerto 50000) y al web service de BES (HTTPS de salida). |
| WinSW | `WinSW-x64.exe` de <https://github.com/winsw/winsw/releases> (rama 2.x). Verifique el hash que publica el proyecto. |
| NSSM | `nssm.exe` de 64 bits (carpeta `win64` del `.zip` de <https://nssm.cc/download>). Ver la nota de abajo sobre la versión. |
| Certificado | Un `.pfx` (o `.key` + `.crt`) para el nombre con que los usuarios abrirán la página. |
| Permisos | Una consola de PowerShell **como administrador**. |
> **Versión de NSSM.** Descargue la compilación **2.24-101** (*pre-release*, `nssm-2.24-101-g897c7ad.zip`,
> carpeta `win64`), no la estable. La estable (2.24, de 2014) puede fallar al iniciar servicios en Windows 10
> y 11 y en Windows Server 2019 o 2022 (mensajes como `Unexpected status SERVICE_PAUSED`); solo debería
> servir en Windows Server 2016. Compruebe con `nssm version` (debe decir `2.24-101-g897c7ad`). La página
> de descargas no publica sumas de verificación: revise el `.zip` según la política de su empresa.
## 2. Publicar (en su equipo de desarrollo o en el servidor)
Desde la raíz del proyecto, con Node 22:
@@ -55,9 +60,9 @@ C:\apps\devolucion-proveedores\
│ └── apps\api\.env ← se crea en el paso 4
├── certificados\ ← el certificado HTTPS (paso 5)
├── logs\ ← los logs del servicio
├── servicio\ ← lo crea el instalador (copia de nssm.exe)
├── instalar-servicio.ps1
├── desinstalar-servicio.ps1
├── devolucion-api.xml.plantilla
└── DEPLOY.md
```
@@ -86,7 +91,7 @@ HTTP_REDIRECT_PORT=80
- **El puerto es el que ponga en `PORT`**: 443 es solo el ejemplo (con él la URL no lleva `:puerto`). Puede
usar cualquiera que esté libre, por ejemplo `PORT=8443`; entonces la URL es `https://servidor:8443`.
WinSW no influye: solo arranca el servicio.
NSSM no influye: solo arranca el servicio.
- `HTTP_REDIRECT_PORT` es opcional. Solo es útil con el 80 (la gente escribe `http://servidor` sin
puerto); con otro puerto solo redirige a quien escriba `http://servidor:<ese puerto>`. Déjelo vacío si
no lo necesita.
@@ -128,7 +133,7 @@ New-NetFirewallRule -DisplayName 'Devolucion Proveedores HTTP (redireccion)' -Di
```powershell
cd C:\apps\devolucion-proveedores
.\instalar-servicio.ps1 -WinSW C:\descargas\WinSW-x64.exe
.\instalar-servicio.ps1 -Nssm C:\descargas\nssm-2.24-101-g897c7ad\win64\nssm.exe
```
Opciones:
@@ -138,9 +143,11 @@ Opciones:
| `-Cuenta 'EMPRESA\svc-devolucion'` | Ejecutar con una cuenta propia en vez de `LocalSystem`. Pide la contraseña y no la guarda en ningún archivo. Esa cuenta necesita el derecho *Iniciar sesión como servicio* y lectura sobre la carpeta. |
| `-UsarCertificadosDelSistema` | Agrega `NODE_OPTIONS=--use-system-ca`. Úselo si Fortinet (u otro firewall) inspecciona el HTTPS de salida con un certificado propio y la descarga de PDF falla por certificado. |
| `-NombreServicio` | Cambia el nombre del servicio (por defecto `DevolucionProveedores`). |
| `-SoloMostrar` | Imprime los comandos de NSSM que ejecutaría y termina, sin instalar nada ni exigir administrador. Úselo para revisarlos antes. |
El script verifica Node 22, los archivos y el `.env`; genera `servicio\devolucion-api.xml` y
`servicio\devolucion-api.exe`; instala el servicio (arranque automático y reinicio si falla) y lo inicia.
El script verifica Node 22, los archivos y el `.env`; copia `nssm.exe` a `servicio\`; instala el servicio
(arranque automático, reinicio a los 10 s si Node se cae, logs a `logs\`) y lo inicia. Si algún ajuste
falla, quita el servicio a medio configurar.
## 8. Verificar
@@ -156,15 +163,40 @@ En una base nueva pulse **Reconstruir** para crear las tablas, campos y el objet
## 9. Logs
WinSW guarda lo que la API escribe por consola en `logs\` (`*.out.log` y `*.err.log`), rotado por
tamaño: 10 MB y 8 archivos. La aplicación no escribe logs por su cuenta.
NSSM guarda lo que la API escribe por consola en `logs\devolucion-api.out.log` y `devolucion-api.err.log`,
y los rota al llegar a 10 MB (los rotados llevan la fecha y la hora en el nombre). La aplicación no escribe
logs por su cuenta.
**NSSM no limita cuántos archivos rotados conserva**: se acumulan. Programe una limpieza periódica, por
ejemplo una tarea que borre los de más de 30 días:
```powershell
Get-ChildItem C:\apps\devolucion-proveedores\logs -Filter 'devolucion-api.*-*.log' |
Where-Object LastWriteTime -lt (Get-Date).AddDays(-30) | Remove-Item
```
- Los errores 4xx/5xx de la API, los fallos y las peticiones lentas al Service Layer, y los eventos de
negocio (planificación creada, PDF descargado) quedan registrados. Las peticiones correctas no.
- Para seguirlo en vivo: `Get-Content C:\apps\devolucion-proveedores\logs\*.out.log -Wait -Tail 50`.
- La contraseña del web service DTE (`@DTE_CONFC`) y las de los usuarios **nunca** se registran.
## 10. Actualizar a una versión nueva
## 10. Administrar el servicio
Con `servicio\nssm.exe` (la copia que dejó el instalador):
```powershell
cd C:\apps\devolucion-proveedores\servicio
.\nssm.exe status DevolucionProveedores
.\nssm.exe restart DevolucionProveedores
.\nssm.exe edit DevolucionProveedores # ventana gráfica con todos los ajustes
.\nssm.exe get DevolucionProveedores AppEnvironmentExtra
```
Para cambiar una variable de entorno del servicio con `nssm set ... AppEnvironmentExtra`, indique **todas** las
variables juntas (reemplaza la lista completa): `NODE_ENV=production NO_COLOR=1 [NODE_OPTIONS=--use-system-ca]`.
Los valores de la aplicación (puerto, SAP, HTTPS) no van aquí: se cambian en el `.env` y se reinicia el servicio.
## 11. Actualizar a una versión nueva
1. Publique la versión nueva (paso 2) y copie la carpeta al servidor, por ejemplo a `C:\nueva\`.
2. Elija una hora en que haya pocos usuarios: **se perderán las sesiones**.
@@ -182,7 +214,7 @@ Start-Service DevolucionProveedores
`/MIR` borra de `app\` lo que ya no exista en la versión nueva; `/XF .env` conserva su configuración.
Los certificados, los logs y el servicio no cambian.
## 11. Desinstalar
## 12. Desinstalar
```powershell
cd C:\apps\devolucion-proveedores
@@ -191,7 +223,7 @@ cd C:\apps\devolucion-proveedores
Detiene y elimina el servicio. No borra archivos ni logs.
## 12. Seguridad
## 13. Seguridad
- **No publique la aplicación en Internet.** El login es el de SAP B1; manténgala en la red interna o
detrás de una VPN.
@@ -199,10 +231,11 @@ Detiene y elimina el servicio. No borra archivos ni logs.
- Dele al servicio la cuenta con menos permisos posible: solo lectura sobre su carpeta y escritura en `logs\`.
- Restrinja la lectura del `.env` si contiene la clave del `.pfx` (paso 4).
## 13. Problemas frecuentes
## 14. Problemas frecuentes
| Síntoma | Causa probable |
|---|---|
| El servicio no inicia (`SERVICE_PAUSED`, `Unexpected status`) | Problema conocido de NSSM 2.24 estable en Windows recientes: use la compilación 2.24-101 (ver el paso 1) y reinstale el servicio. |
| El servicio se inicia y se detiene | Mire `logs\*.err.log`. Suele ser una ruta mal escrita en el `.env` (`No se pudo leer HTTPS_PFX_PATH (…)`) o el puerto ocupado (`EADDRINUSE`). |
| `WEB_DIST_DIR no contiene un index.html` | Se copió la carpeta `app` incompleta: falta `app\apps\web\dist\web\browser`. |
| Puerto 443 o 80 ocupado | IIS u otro programa lo usa. Cambie `PORT` / `HTTP_REDIRECT_PORT` en el `.env` y las reglas del firewall. |