109 lines
5.7 KiB
Markdown
109 lines
5.7 KiB
Markdown
# Despliegue en Windows (servicio con NSSM)
|
|||
|
|
|
||
|
|
El demonio (`main.py`) corre como **servicio de Windows** gestionado con [NSSM](https://nssm.cc): arranca con el servidor, se reinicia solo si se cae y se detiene de forma ordenada. La carpeta `deploy/` trae los scripts.
|
||
|
|
|
||
|
|
> Los scripts de `deploy/` se revisaron con el analizador de PowerShell (sintaxis correcta) pero **no se ejecutaron en un Windows real**. Pruébelos primero en un servidor de pruebas.
|
||
|
|
|
||
|
|
## Requisitos del servidor
|
||
|
|
|
||
|
|
| Requisito | Detalle |
|
||
|
|
|-----------|---------|
|
||
|
|
| Windows | Server 2016 o superior, o Windows 10/11 |
|
||
|
|
| Python | 3.11 o superior, **64 bits** (el cliente de SAP HANA, `hdbcli`, lo requiere) |
|
||
|
|
| Git y NSSM | `git` en el PATH y `nssm.exe` en el PATH (<https://nssm.cc>) |
|
||
|
|
| Red hacia fuera | `login.microsoftonline.com` y `graph.microsoft.com` (443) |
|
||
|
|
| Red hacia SAP | Service Layer (`SAP_B1_URL`, puerto 50000 por defecto) y HANA (`HANA_SERVER`, puerto 30015) |
|
||
|
|
| Ruta de red | Acceso de lectura y escritura a `RUTA_RED_FACTURACION` (recurso UNC) |
|
||
|
|
| Cuenta de servicio | Una cuenta de dominio, por ejemplo `ABERIO\svc_facturas`, con acceso a esa ruta de red |
|
||
|
|
| Zona horaria | El código asume hora de Lima (UTC-5) para la fecha y hora de recepción que ve el proveedor |
|
||
|
|
|
||
|
|
**La cuenta de servicio es importante.** Por defecto un servicio corre como `LocalSystem`, que **no ve recursos de red**: la copia a la ruta de facturación electrónica fallaría. Use una cuenta con permiso sobre ese recurso.
|
||
|
|
|
||
|
|
## Instalación
|
||
|
|
|
||
|
|
En PowerShell **como administrador**:
|
||
|
|
|
||
|
|
```powershell
|
||
|
|
cd C:\apps
|
||
|
|
git clone https://unasgeorge.vaquita-hadar.ts.net/george/descarga_factura_transporte.git
|
||
|
|
cd descarga_factura_transporte
|
||
|
|
git checkout v1.2.0 # siempre una versión etiquetada, no main
|
||
|
|
|
||
|
|
py -3 -m venv venv
|
||
|
|
venv\Scripts\python -m pip install -r requirements.txt
|
||
|
|
|
||
|
|
copy .env.example .env # y completar los valores
|
||
|
|
```
|
||
|
|
|
||
|
|
Complete el `.env` (cómo obtener las credenciales de Microsoft: [configurar_msal.md](configurar_msal.md)). **Empiece con `NOTIFICACION_MODO=prueba`**: las respuestas van al equipo y no a los proveedores. Defina `NOTIFICACION_EQUIPO` y `LOGO_URL`.
|
||
|
|
|
||
|
|
### Verificar antes de instalar el servicio
|
||
|
|
|
||
|
|
```powershell
|
||
|
|
venv\Scripts\python tools\verificar_conexiones.py
|
||
|
|
```
|
||
|
|
|
||
|
|
Revisa, sin modificar nada ni imprimir secretos: el `.env`, el token y la lectura del buzón de Microsoft Graph, SAP Service Layer, SAP HANA y la ruta de red de facturación (que debe ser accesible y escribible con la cuenta del servicio). Termina con código 1 si algo falla. Opcionalmente, las pruebas (no tocan SAP ni Outlook):
|
||
|
|
|
||
|
|
```powershell
|
||
|
|
venv\Scripts\python -m pip install pytest==9.1.1
|
||
|
|
venv\Scripts\python -m pytest -q
|
||
|
|
```
|
||
|
|
|
||
|
|
### Instalar y arrancar el servicio
|
||
|
|
|
||
|
|
```powershell
|
||
|
|
.\deploy\instalar_servicio.ps1 -Cuenta "ABERIO\svc_facturas" # pide la contraseña
|
||
|
|
nssm start descarga_factura_transporte
|
||
|
|
```
|
||
|
|
|
||
|
|
El script configura: arranque automático, directorio de trabajo del proyecto, reinicio automático a los 30 s si el proceso muere, parada con Ctrl+C (20 s de gracia), rotación de la salida del servicio a 10 MB y las variables `PYTHONUTF8=1` y `PYTHONIOENCODING=utf-8` (sin ellas los emojis del log dan error en la consola de Windows).
|
||
|
|
|
||
|
|
## Comprobar que funciona
|
||
|
|
|
||
|
|
```powershell
|
||
|
|
Get-Service descarga_factura_transporte
|
||
|
|
Get-Content logs\descarga_factura_transporte.log -Wait -Tail 30
|
||
|
|
```
|
||
|
|
|
||
|
|
En el log, al arrancar, debe verse `🚀 Demonio iniciado … (versión 1.2.0)`, y `config_validator` anuncia el modo de notificación (`PRUEBA` o `REAL`).
|
||
|
|
|
||
|
|
## Operación
|
||
|
|
|
||
|
|
| Tema | Detalle |
|
||
|
|
|------|---------|
|
||
|
|
| Logs de la aplicación | `logs\descarga_factura_transporte.log`, rotación diaria, 30 días |
|
||
|
|
| Salida del servicio | `logs\servicio.out.log` y `servicio.err.log` (10 MB, rotan). Mire `servicio.err.log` si el servicio arranca y se detiene |
|
||
|
|
| Cambiar el `.env` | `nssm restart descarga_factura_transporte` |
|
||
|
|
| Horarios | `HORARIOS` en `main.py` (24 h cubiertas, ver [main.md](main.md)) |
|
||
|
|
| Copia de seguridad | `emails.db` guarda los correos procesados y los códigos de seguimiento. Cópielo con el servicio detenido, o con `sqlite3 emails.db ".backup respaldo.db"` |
|
||
|
|
| Espacio en disco | `adjuntos\` y `resultado\` **no se limpian solos**: planifique una limpieza periódica |
|
||
|
|
| Pasar a modo real | Cuando el equipo haya validado las respuestas: `NOTIFICACION_MODO=real` y reiniciar |
|
||
|
|
|
||
|
|
## Actualizar y volver atrás (rollback)
|
||
|
|
|
||
|
|
Siempre a una **versión etiquetada** (ver [CHANGELOG](../CHANGELOG.md)):
|
||
|
|
|
||
|
|
```powershell
|
||
|
|
.\deploy\actualizar.ps1 -Version v1.2.0
|
||
|
|
.\deploy\actualizar.ps1 -Version v1.1.0 # volver a la anterior
|
||
|
|
```
|
||
|
|
|
||
|
|
El script detiene el servicio, hace `git checkout` de la etiqueta, instala las dependencias y arranca de nuevo (aunque algo falle, vuelve a levantar lo que había). No toca el `.env` ni `emails.db`. Se niega a actuar si hay cambios locales sin guardar.
|
||
|
|
|
||
|
|
## Desinstalar
|
||
|
|
|
||
|
|
```powershell
|
||
|
|
.\deploy\desinstalar_servicio.ps1 # no borra el proyecto, el .env ni emails.db
|
||
|
|
```
|
||
|
|
|
||
|
|
## Problemas frecuentes
|
||
|
|
|
||
|
|
| Síntoma | Causa probable |
|
||
|
|
|---------|----------------|
|
||
|
|
| El servicio arranca y se detiene enseguida | Falta el `.env`, o `config_validator` rechazó una variable: ver `logs\servicio.err.log` |
|
||
|
|
| `Access is denied` al copiar a la ruta de red | El servicio corre como `LocalSystem`. Reinstale con `-Cuenta` o cambie la cuenta en `services.msc` |
|
||
|
|
| `UnicodeEncodeError` en la salida del servicio | Falta `PYTHONUTF8=1`: reinstale con `instalar_servicio.ps1` |
|
||
|
|
| `AADSTS7000222` / `AADSTS700016` | Secret vencido / `CLIENT_ID` y `TENANT_ID` de aplicaciones distintas: ver [configurar_msal.md](configurar_msal.md) |
|
||
|
|
| `ConnectTimeout` hacia SAP o HANA | VPN o firewall: abra el puerto 50000 (Service Layer) y 30015 (HANA) desde el servidor |
|
||
|
|
| Los correos llegan sin logo | `LOGO_URL` vacío o no accesible públicamente |
|