Actualizar n8n en Producción con Windows, IIS y NSSM: guía real y lecciones aprendidas

En ZelvaIT utilizamos n8n como motor central de automatizaciones para integraciones, flujos de datos y productos basados en IA. Al tratarse de un componente crítico, cualquier cambio en su versión impacta directamente en producción.

En este artículo documentamos una actualización real de n8n en un servidor productivo, los problemas que surgieron, las hipótesis incorrectas que descartamos, las soluciones aplicadas y, sobre todo, las lecciones operativas que quedaron como procedimiento oficial.

Este no es un tutorial idealizado. Es la experiencia real.


1. Contexto técnico inicial

Nuestro entorno es el siguiente:

  • Windows Server
  • n8n instalado vía npm global
  • n8n corriendo como servicio Windows mediante NSSM
  • IIS como reverse proxy (ARR) hacia n8n
  • Base de datos SQLite (configuración por defecto)
  • Servidor 100% producción

Este contexto es importante porque muchos problemas no aparecen en Docker ni en Linux, pero sí en Windows con servicios persistentes.

Servidor n8n ZelvaIT

2. El punto de partida: “ya actualicé, pero la UI dice lo contrario”

El primer síntoma fue simple, pero engañoso:

  • Se ejecutó npm install -g n8n@next
  • npm finalizó correctamente (con varios warnings)
  • Al ingresar a la UI, n8n seguía mostrando una versión antigua (1.106.x)
  • Además, aparecía el banner de “update available”

A partir de ahí surgió la duda clásica:

“¿Debo actualizar versión por versión hasta llegar a la última?”

La respuesta corta es no, pero llegar a esa conclusión requirió entender qué estaba pasando realmente.


3. Hipótesis iniciales (y por qué eran incorrectas)

Antes de llegar a la causa real, se evaluaron varias posibilidades:

❌ Problema de npm o dependencias

Los warnings de ERESOLVE, peer dependencies y paquetes deprecated parecían sospechosos, pero npm completó la instalación correctamente. No había errores fatales.

❌ IIS cacheando la versión

IIS no ejecuta n8n, solo actúa como reverse proxy. No tiene control sobre la versión del backend.

❌ Necesidad de actualizar incrementalmente

n8n no requiere upgrades secuenciales. Cada versión incluye las anteriores.

Todas estas hipótesis eran razonables, pero ninguna explicaba el comportamiento observado.


4. El hallazgo clave: el proceso correcto… pero el servicio equivocado

El punto de quiebre llegó al ejecutar:

n8n --version

El resultado fue claro:

2.2.1

Es decir:

  • ✅ n8n sí estaba actualizado
  • ❌ pero no era la versión que estaba corriendo en producción

Al intentar iniciar n8n manualmente:

n8n start

apareció el mensaje definitivo:

n8n's port 5678 is already in use

Esto indicaba que otra instancia de n8n seguía viva, escuchando el puerto.


5. La causa real: NSSM y servicios persistentes en Windows

La clave estaba en algo que suele olvidarse en Windows:

Actualizar el binario no reinicia el servicio que ya está corriendo

Al verificar el estado del servicio:

nssm status n8n

el resultado fue:

SERVICE_RUNNING

Esto explicaba todo:

  • El servicio NSSM seguía ejecutando la instancia cargada en memoria
  • Windows no “recarga” el binario automáticamente
  • IIS seguía apuntando a ese proceso viejo
  • Por eso la UI no cambiaba

No era un problema de versiones.
Era un problema de ciclo de vida del servicio.


6. La solución correcta (y definitiva)

El procedimiento correcto fue:

cd C:\nssm\win64
nssm stop n8n

netstat -ano | findstr :5678   (confirmar puerto libre)

npm install -g n8n@2.1.4

n8n --version

nssm start n8n

Luego de esto:

  • El puerto quedó correctamente reasignado
  • La UI mostró la versión correcta
  • Los workflows permanecieron intactos
  • No fue necesario restaurar snapshot

7. Decisión estratégica: versión estable vs “latest”

Durante el proceso surgió otra pregunta clave:

“¿Conviene usar la última versión o una versión estable?”

Dado que el servidor es 100% producción, se decidió fijar la versión 2.1.4, priorizando:

  • estabilidad
  • menor ruido de dependencias
  • menor riesgo operativo

Las versiones @next o incluso @latest quedaron reservadas para entornos de prueba.


8. Explorando la nueva UI: el caso del Chat experimental

Al explorar la UI actualizada apareció una nueva opción: Chat.

Al probarla, surgió el error:

SQLITE_CONSTRAINT: NOT NULL constraint failed: chat_hub_sessions.lastMessageAt

El análisis mostró que:

  • El Chat UI es una feature experimental
  • Está pensada para AI + agentes internos
  • Tiene problemas conocidos con SQLite
  • No está lista para producción

La conclusión fue clara:

No es un chat para clientes, ni una herramienta madura para operación diaria.


9. La reflexión final: el verdadero valor estaba en otra parte

Aunque el Chat UI no era usable, la idea detrás sí era valiosa:

Usar un chat como acelerador interno para diseñar automatizaciones y nuevos productos.

De ahí nació una decisión estratégica:

  • ❌ No usar el Chat experimental de n8n
  • ✅ Diseñar un Copiloto interno propio, usando:
    • una UI controlada
    • n8n como backend
    • IA como asistente de diseño, análisis y documentación

Un enfoque mucho más estable, reutilizable y alineado al negocio.


10. Resultado final: más que una actualización

Lo que comenzó como una “simple actualización” terminó dejando:

  • Un procedimiento oficial de upgrade documentado
  • Una política clara de versionado en producción
  • Mejor entendimiento de n8n en Windows
  • Criterio para evaluar features experimentales
  • La base conceptual de un Dev Copilot interno para ZelvaIT

Conclusión

Actualizar software en producción no es solo ejecutar comandos.
Es entender:

  • cómo corre el sistema
  • qué procesos están vivos
  • qué decisiones impactan estabilidad
  • y qué herramientas realmente agregan valor

En ZelvaIT creemos que documentar estos procesos es parte del trabajo profesional, porque evita repetir errores y convierte incidentes en conocimiento.

Si estás usando n8n en producción, especialmente en Windows, esperamos que esta experiencia te ahorre tiempo, confusión y dolores de cabeza.