⚠️ ADVERTENCIA: NO HAY VUELTA ATRÁS
La actualización a v2.0 modifica tu base de datos de forma irreversible.
Una vez que actualices:
- →❌ No puedes volver a v1.x con la misma base de datos
- →❌ No existe un rollback automático
- →❌ Tu única opción de "retroceso" es restaurar desde backup
¿Qué significa esto?
Si actualizas y algo se rompe, no puedes simplemente hacer docker-compose down y volver a la imagen anterior. Tu base de datos ya habrá sido migrada al esquema de v2.0, y v1.x no sabrá qué hacer con ella.
Por eso el backup NO es opcional. Es obligatorio.
Ahora que os he avisado, ya puedo continuar...
Llevo más de un año trabajando con despliegues de n8n, y cuando vi el anuncio de v2.0, mi primer pensamiento no fue "qué funciones tan geniales", fue "¿cuántos workflows en producción voy a tener que arreglar?"
¿Y sabes qué? Este lanzamiento es realmente bueno, pero van a romper tus cosas si no te preparas.
La Línea de Tiempo (Marca tu calendario)
- →Beta: 8 de diciembre, 2025
- →Estable: 15 de diciembre, 2025
- →Tu fecha límite para probar: ahora mismo
La versión 1.x tendrá 3 meses de parches de seguridad después del lanzamiento de v2, y luego se acabó.
Las cosas buenas
Autoguardado viene en camino. Sí, por fin. ¿Después de cuántos años de gente perdiendo trabajo? Mejor tarde que nunca.
También: interfaz de canvas actualizada, nueva barra lateral, y "sorpresas".
Pero seamos realistas, no estás aquí por las actualizaciones de UI.
Las cosas que realmente van a romper tus workflows
Seguridad: Están bloqueando todo
1. El nodo Code ya no puede acceder a variables de entorno
bash
N8N_BLOCK_ENV_ACCESS_IN_NODE=true # Este es ahora el valor por defecto
Si has sido perezoso y estabas accediendo a process.env.ALGUN_SECRETO en tus nodos Code... sí, eso se acabó.
¿La solución?:
- →Configurarlo de vuelta a
false (lo cual anula el propósito)
He visto demasiada gente guardando API keys en variables de entorno y accediéndolas en nodos Code. Esto fuerza mejores prácticas.
2. Los Task Runners son obligatorios
bash
N8N_RUNNERS_ENABLED=true
Todas las ejecuciones de nodos Code ahora corren en task runners para aislamiento. Esto es bueno para seguridad, pero tu infraestructura necesita manejarlo.
Ahora tienen que estar en modo externo que es lo mas seguro.
3. Nodo Python Code: reescritura completa
Eliminaron Pyodide (el Python basado en navegador). Ahora es Python nativo solamente, task runners requeridos, modo externo obligatorio.
Lo que se rompe:
- →Variable
_input (eliminada)
- →Notación de acceso por punto (eliminada)
- →Cualquier nodo Python Code sin configuración apropiada de task runner (roto)
Esto es mejor a largo plazo, pero el dolor de migración es importante. Revisa todos los nodos Python Code que tengas.
4. ExecuteCommand y LocalFileTrigger: deshabilitados por defecto
Por fin. Estos nodos son pesadillas de seguridad. Permiten a los usuarios ejecutar comandos arbitrarios del sistema y acceder al sistema de archivos.
Están deshabilitados ahora. Si absolutamente los necesitas (y probablemente no), tienes que habilitarlos explícitamente:
bash
NODES_EXCLUDE="[]" # O solo eliminar estos nodos específicos
5. Los Callbacks de OAuth Necesitan Autenticación
bash
N8N_SKIP_AUTH_ON_OAUTH_CALLBACK=false # Nuevo valor por defecto
Antes de actualizar, prueba cada integración OAuth. Slack, Google, lo que sea que tengas conectado, pruébalo todo.
6. Las Operaciones con Archivos Están en Sandbox
bash
N8N_RESTRICT_FILE_ACCESS_TO=~/.n8n-files # Nuevo valor por defecto
Los nodos ReadWriteFile y ReadBinaryFiles solo pueden tocar archivos en este directorio ahora. Bueno para seguridad, molesto si has estado leyendo archivos de ubicaciones aleatorias.
7. Permisos de archivos de configuración: seguridad estilo SSH
Tus archivos de configuración necesitan permisos 0600 (solo el propietario puede leer y escribir).
bash
N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
Usuarios de Windows: Esto no funciona en Windows. Configúralo a false.
Usuarios de Linux/Mac: Ejecuta chmod 600 en tus archivos de configuración o n8n no arrancará.
Cambios en Base de Datos (Los dolorosos)
MySQL/MariaDB: eliminados
Se acabó. Solo PostgreSQL o SQLite. Esto fue deprecado en v1.0, si todavía estás en MySQL, has tenido un año para migrar.
Usa la herramienta de migración de base de datos o estás fregado.
SQLite: Driver Legacy eliminado
Solo queda el driver de pooling. Es más rápido (10x en benchmarks), usa modo WAL, y es el nuevo valor por defecto.
bash
DB_SQLITE_POOL_SIZE=2 # Auto-configurado
La mayoría de la gente no notará este cambio. Si lo haces, probablemente es porque algo estaba roto antes.
Datos binarios: No más modo In-memory
¿El modo default que mantiene datos binarios en memoria durante la ejecución? Se fue.
Tus opciones:
- →
filesystem (por defecto para instancia única)
- →
database (por defecto para modo queue)
- →
s3 (si eres elegante)
Asegúrate de tener espacio en disco. Si estás procesando archivos grandes y de repente te quedas sin espacio, esta es la razón.
Cambios de comportamiento (los sutiles)
Subworkflow + Wait Node = Arreglado
Antes: El workflow padre recibía el input de los nodos Wait en workflows hijos (lo cual no tenía sentido)
Ahora: El workflow padre recibe el output del final del workflow hijo (lo cual es correcto)
Si tienes workflows llamando subworkflows con nodos Wait, revísalos. El cambio de comportamiento es correcto, pero tu lógica podría depender del comportamiento roto anterior.
Infierno de configuración
Actualización de dotenv
El parsing de tu archivo .env es diferente ahora.
Cambios:
- →Los backticks necesitan comillas ahora
- →
# siempre inicia un comentario (no más valores conteniendo #)
- →Los valores multilínea funcionan ahora
Revisa tus archivos .env. Especialmente si tienes caracteres raros en contraseñas o tokens.
Cosas elimandas:
- →
QUEUE_WORKER_MAX_STALLED_COUNT
- →Opción CLI
n8n --tunnel (usa ngrok o Cloudflare Tunnel)
- →
update:workflow --all --active=true (buen viaje, esto era peligroso)
Nodos eliminados:
- →Spontit
- →crowd.dev
- →Kitemaker
Setup de Docker: Viejo vs Nuevo (la parte que realmente necesitas)
Bueno, suficiente teoría. Así es como tu docker-compose realmente necesita verse.
yaml
services:
n8n:
image: n8nio/n8n:latest
container_name: n8n
restart: always
ports:
- "5678:5678"
environment:
- N8N_HOST=tu-dominio.com
- N8N_PORT=5678
- N8N_PROTOCOL=https
- WEBHOOK_URL=https://tu-dominio.com/
- GENERIC_TIMEZONE=Europe/Berlin
# Base de datos
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=n8n_password
# Estos eran los valores por defecto (y problemas de seguridad)
- N8N_BLOCK_ENV_ACCESS_IN_NODE=false # Los nodos Code podían acceder a env vars
- N8N_RUNNERS_ENABLED=false # Sin task runners
- N8N_SKIP_AUTH_ON_OAUTH_CALLBACK=true # Sin auth en callbacks OAuth
volumes:
- n8n_data:/home/node/.n8n
- ./n8n-files:/files # Archivos donde sea que quieras
depends_on:
- postgres
postgres:
image: postgres:15
container_name: n8n_postgres
restart: always
environment:
- POSTGRES_USER=n8n
- POSTGRES_PASSWORD=n8n_password
- POSTGRES_DB=n8n
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
n8n_data:
postgres_data:
Esto funcionaba bien, pero tenía agujeros de seguridad por los que podías pasar un camión.
Para la mayoría de la gente, esto es suficiente. Task runners corren como procesos hijos dentro del mismo contenedor.
yaml
services:
n8n:
image: n8nio/n8n:latest
container_name: n8n
restart: always
ports:
- "5678:5678"
environment:
- N8N_HOST=tu-dominio.com
- N8N_PORT=5678
- N8N_PROTOCOL=https
- WEBHOOK_URL=https://tu-dominio.com/
- GENERIC_TIMEZONE=Europe/Berlin
# Base de datos
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=n8n_password
# Nuevo v2.0 - Modo interno (simple)
- N8N_RUNNERS_ENABLED=true # ¡Solo esto!
- N8N_BLOCK_ENV_ACCESS_IN_NODE=true
- N8N_SKIP_AUTH_ON_OAUTH_CALLBACK=false
# Restricciones de Acceso a Archivos
- N8N_RESTRICT_FILE_ACCESS_TO=/home/node/.n8n-files
# Permisos de Archivos (Solo Linux/Mac)
- N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
# - N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=false # Para Windows
# Almacenamiento de Datos Binarios
- N8N_DEFAULT_BINARY_DATA_MODE=filesystem
# Seguridad del Nodo Git
- N8N_GIT_NODE_DISABLE_BARE_REPOS=true
# Si quieres permitir el uso de ExecuteCommand y LocalFileTrigger (deshabilitados por defecto)
- NODES_EXCLUDE=[]
volumes:
- n8n_data:/home/node/.n8n
- n8n_files:/home/node/.n8n-files
depends_on:
- postgres
postgres:
image: postgres:15
container_name: n8n_postgres
restart: always
environment:
- POSTGRES_USER=n8n
- POSTGRES_PASSWORD=n8n_password
- POSTGRES_DB=n8n
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
n8n_data:
n8n_files:
postgres_data:
Cuándo usar modo interno:
- →Setup más simple
- →No necesitas Python Code nodes
- →No tienes requisitos de seguridad extremos
- →La mayoría de los casos de uso
Solo necesitas esto si:
- →Usas Python Code nodes (modo externo es obligatorio para Python)
- →Quieres aislamiento máximo de seguridad
- →Estás corriendo en modo queue con workers
yaml
services:
n8n:
image: n8nio/n8n:latest
container_name: n8n
restart: always
ports:
- "5678:5678"
environment:
- N8N_HOST=tu-dominio.com
- N8N_PORT=5678
- N8N_PROTOCOL=https
- WEBHOOK_URL=https://tu-dominio.com/
- GENERIC_TIMEZONE=Europe/Berlin
# Base de datos
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=n8n_password
# Nuevo v2.0 - Modo Externo
- N8N_RUNNERS_ENABLED=true
- N8N_RUNNERS_MODE=external
- N8N_RUNNERS_BROKER_LISTEN_ADDRESS=0.0.0.0 # Permitir conexiones externas
- N8N_RUNNERS_AUTH_TOKEN=${N8N_RUNNERS_AUTH_TOKEN}
- N8N_NATIVE_PYTHON_RUNNER=true # Para Python Code nodes
- N8N_BLOCK_ENV_ACCESS_IN_NODE=true
- N8N_SKIP_AUTH_ON_OAUTH_CALLBACK=false
# Restricciones de Acceso a Archivos
- N8N_RESTRICT_FILE_ACCESS_TO=/home/node/.n8n-files
# Permisos de Archivos (Linux/Mac)
- N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
# - N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=false # Windows
# Almacenamiento de Datos Binarios
- N8N_DEFAULT_BINARY_DATA_MODE=filesystem
# Seguridad del Nodo Git
- N8N_GIT_NODE_DISABLE_BARE_REPOS=true
# Si quieres permitir el uso de ExecuteCommand y LocalFileTrigger (deshabilitados por defecto)
- NODES_EXCLUDE="[]"
volumes:
- n8n_data:/home/node/.n8n
- n8n_files:/home/node/.n8n-files
depends_on:
- postgres
# Task Runner Externo (contenedor separado)
n8n-runner:
image: n8nio/runners:latest
container_name: n8n_runner
restart: always
environment:
# Conecta al broker en n8n via HTTP/WebSocket en puerto 5679
- N8N_RUNNERS_TASK_BROKER_URI=http://n8n:5679
- N8N_RUNNERS_AUTH_TOKEN=${N8N_RUNNERS_AUTH_TOKEN} # Mismo token que n8n
depends_on:
- n8n
postgres:
image: postgres:15
container_name: n8n_postgres
restart: always
environment:
- POSTGRES_USER=n8n
- POSTGRES_PASSWORD=n8n_password
- POSTGRES_DB=n8n
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
n8n_data:
n8n_files:
postgres_data:
Genera tu token de autenticación:
Añádelo a tu archivo .env:
bash
N8N_RUNNERS_AUTH_TOKEN=tu-token-generado-aqui
¿Qué Cambió? Comparación Visual
Anterior (v1.x):
- →n8n container
- →postgres container
- →Sin runners, sin aislamiento
New (v2.0) - Interno:
- →n8n container (con runners internos)
- →postgres container
- →Sin contenedores extra
New (v2.0) - Externo:
- →n8n container (actúa como task broker en puerto 5679)
- →n8n-runner container (se conecta a n8n via WebSocket)
- →postgres container
- →Auth token para comunicación segura
- →No Redis (a menos que estés en queue mode)
Lista de Verificación de Migración
Para modo interno (mayoría de la gente):
Para modo externo (usuarios de Python o alta seguridad):
Problemas Comunes
"Task runner no se conecta"
Verifica:
- →Token de auth idéntico en n8n y runner
- →URI del broker correcto:
http://n8n:5679 (o el nombre de tu contenedor)
- →
N8N_RUNNERS_BROKER_LISTEN_ADDRESS=0.0.0.0 en n8n (para aceptar conexiones externas)
"OAuth dejó de funcionar"
No probaste con N8N_SKIP_AUTH_ON_OAUTH_CALLBACK=false antes de actualizar.
"Operaciones de archivo fallando"
Los archivos no están en /home/node/.n8n-files. Muévelos o ajusta la ruta.
"n8n no arranca - error de permisos"
Archivos de config necesitan chmod 600. Usuarios de Windows: N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=false.
"Error de no autorizado desde runner"
Los tokens no coinciden. Verifica tu .env.
Cómo no arruinar esto
Paso 1: revisa el reporte de migración
Settings → Migration Report (necesitas acceso de admin)
Disponible desde v1.121.0. Ejecútalo ahora.
Paso 2: decide tu modo de runner
¿Usas Python Code nodes? → Modo externo obligatorio
¿Necesitas máxima seguridad? → Modo externo
¿Todo lo demás? → Modo interno es suficiente
Paso 3: si vas con modo externo, genera token
bash
openssl rand -hex 32 >> .env
Edita .env:
bash
N8N_RUNNERS_AUTH_TOKEN=tu-token-aqui
Configura permisos:
Paso 4: prueba en staging
bash
N8N_RUNNERS_ENABLED=true
N8N_SKIP_AUTH_ON_OAUTH_CALLBACK=false
N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
Paso 5: revisa cada nodo Code
Especialmente:
- →Cualquier cosa usando
process.env
- →Todos los nodos Python Code
- →Operaciones de archivo
Paso 6: prueba OAuth
Todas las integraciones. Manualmente. Sin excepciones.
Paso 7: respalda todo
Base de datos, workflows, credenciales, configs, directorio .n8n completo.
Paso 8: Ayuda a encontrar los bugs
Reporta los bugs ya sea en un issue en el repositorio o en el foro de la comunidad n8n.
Mi Opinión
Este es el lanzamiento más significativo de n8n desde 1.0. Las mejoras de seguridad son necesarias.
La mayoría de la gente estará bien con modo interno, es simple, solo configuras N8N_RUNNERS_ENABLED=true y listo. No necesitas contenedores extra, no necesitas Redis, no necesitas tokens de auth complicados.
Modo externo solo es necesario si:
- →Usas Python Code nodes (obligatorio)
- →Tienes requisitos de seguridad extremos
- →Estás corriendo queue mode con múltiples workers
Si estás corriendo n8n en producción (como yo todos los días), tómate esto en serio. Presupuesta tiempo real para pruebas y migración. No solo hagas docker pull y esperes lo mejor.
Las buenas noticias? Después de migrar, tu instancia será más segura, más estable, y mejor posicionada para futuras actualizaciones.
Recursos