Qué es Docker: conocimientos mínimos necesarios para principiantes de n8n
El lugar donde más fácilmente se atasca la instalación de n8n no es n8n en sí, sino el Docker que tiene delante. Siguiendo un tutorial se copian las cinco líneas de comandos, el container arranca y con un par de clics en la interfaz también funciona; al día siguiente se vuelve y resulta que todos los workflows han desaparecido — la causa es solo que en esas cinco líneas faltaba un -v。
Este artículo solo trata la parte de Docker que se necesita para instalar n8n: image, container, volume, port. Cuatro palabras. En cuanto a los modos de red, Compose o construir la image uno mismo, eso se deja para cuando realmente se vaya a usar; aprenderlo antes también se olvida.
El requisito previo es solo uno: poder escribir comandos en la terminal y saber qué es un «port». No haber tocado Docker nunca no afecta en absoluto.
- Por qué n8n termina siempre instalado en Docker
- Cuatro palabras: image, container, volume, port
- Primero instalar Docker
- Levantar un n8n, tres pasos
- Cómo saber que está bien instalado
- En qué archivo están realmente los datos
- Seis errores que realmente se encuentran
- Varios puntos de seguridad relacionados con n8n
Por qué n8n termina siempre instalado en Docker
La página oficial de instalación ofrece varias vías: instalación global con npm, ejecución directa con npx, Docker, versión de escritorio. Las dos primeras son las más ligeras, con una npm install -g n8n y listo; el problema es que atan n8n al Node de tu máquina. n8n es exigente con la versión de Node, la documentación indica el rango de 20.19 a 24.x. El día que actualices Node a 26 por otro proyecto, n8n deja de funcionar en consecuencia, y el error ni siquiera tiene por qué decirlo en lenguaje claro.
Docker cambia el enfoque: empaqueta n8n junto con el Node, las librerías del sistema y los datos de zona horaria que necesita en un solo paquete, y este paquete se ejecuta igual en la máquina de cualquiera. Entré expresamente a la image 2.43.7 para echar un vistazo: Node es 26.7.0 y la image base es Alpine. Todo esto no tiene nada que ver con que en tu host esté instalado Node 18 o 26.
El costo también hay que dejarlo claro. Añades una capa más que mantener: la image ocupa disco (2.43.7 descomprimida son 1.8 GB), si algo falla tienes que revisar un log más, y actualizar pasa de «npm update» a «cambiar la image y volver a ejecutar». Me parece que vale la pena: al actualizar, cambias el tag, borras el container y vuelves a ejecutar, tres minutos, sin preocuparte por la versión de Node.
Si solo vas a trastear en local dos días, no te recomiendo Docker, npm es más rápido. Si planeas ejecutarlo a largo plazo, o dárselo a compañeros, ve directo a Docker, no des rodeos.
Cuatro palabras: image, container, volume, port
Image
La image es un paquete de solo lectura ya preparado por otros, dentro hay un sistema de archivos completo capaz de ejecutar n8n.n8nio/n8n Es el nombre,2.43.7 es el tag. Bajo un mismo nombre cuelga un montón de tags, un tag corresponde a una versión.
El tag se escribe latest, significa «última versión estable». En producción no recomiendo escribirlo así: cualquier día al reiniciar el container se descarga la nueva image sin querer, el comportamiento cambia y no sabes ni por dónde investigar. Fija el número de versión, trata la actualización como una tarea aparte.

docker pull es elque tienes que teclear
Containerdocker run La image está muerta.
卷
El proceso que se ejecuta después es lo que se llama container. El container equivale a la image más una capa escribible, cualquier cosa que modifiques dentro se escribe en esta capa. Si borras el container, esta capa desaparece con él — esta frase es el origen de todos los problemas posteriores. /home/node/.n8n, la base de datos, las claves de cifrado y los registros de eventos están ahí.
Lo conté: un directorio recién creado con la cuenta owner y con un workflow ejecutado una vez .n8n ocupa 5.5 MB. De eso, database.sqlite 1.5 MB, y además hay un archivo de 4 MB -wal . Con tan poco, si se pierde, hay que empezar de cero.
port
-p 5678:5678, a la izquierda de los dos puntos está el port del host, a la derecha el port dentro del container. El n8n dentro del container siempre escucha en 5678 (salvo que cambies N8N_PORT), si quieres usar otro número por fuera, solo cambias el de la izquierda:-p 8080:5678。
escrito como 127.0.0.1:5678:5678 solo se vincula a la máquina local, desde fuera no se puede conectar. Cuando hago pruebas uso siempre esta forma, para no olvidarme de cerrarlo.
Primero instala Docker
En Ubuntu / Debian lo más sencillo es el script oficial:
curl -fsSL https://get.docker.com | sh
añade el repositorio oficial, instala docker-ce y trae el plugin compose. Si te incomoda «pasar directamente a sh lo que sale de curl», usa el método oficial con apt, los pasos están en la documentación de Docker, solo que es más largo.
Después de instalar, ejecuta dos comandos para ver la versión:
docker --version
# Docker version 29.1.3, build 29.1.3-0ubuntu3~24.04.2
Mi 232 es Ubuntu 24.04 + Docker 29.1.3. Tú puedes usar 24 o 25, los comandos no cambian.
Docker por defecto requiere root o sudo. Algunos dicen que basta con añadir el usuario al docker grupo para no usar sudo; eso es cierto, pero equivale a darle a ese usuario permisos de root, la razón está en la sección de seguridad.
Levantar un n8n, tres pasos
Paso uno: crear el volumen
docker volume create n8n_data
# n8n_data
Si devuelve el nombre del volumen, ya está creado. También se puede omitir este paso,docker run escribiendo en -v n8n_data:/home/node/.n8n se creará automáticamente; pero crearlo una vez primero te permite confirmar que realmente existe.
Paso dos: ponerlo en marcha
docker run -d
--name n8n
-p 127.0.0.1:5678:5678
-e TZ=Asia/Shanghai
-e GENERIC_TIMEZONE=Asia/Shanghai
-e N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
-v n8n_data:/home/node/.n8n
n8nio/n8n:2.43.7
Comparado con el comando original de la documentación oficial, cambié dos cosas.
Una es que añadí -d. La documentación da docker run -it --rm, que se ejecuta en primer plano; al cerrar la terminal o pulsar Ctrl+C, n8n se detiene;--rm además elimina el contenedor de paso. Para depurar es muy limpio así, pero para ejecución a largo plazo no sirve; añade -d para dejarlo en segundo plano.
La otra es que antes del puerto añadí 127.0.0.1:. El documento dice -p 5678:5678, eso equivale a estar atado a 0.0.0.0, siempre que la máquina tenga IP pública, cualquiera que escanee el 5678 podrá ver tu página de inicio de sesión. En mi máquina 232 el 5678 está ocupado, en la práctica uso -p 127.0.0.1:5681:5678, la relación de mapeo es la misma.
Hay que proporcionar ambas variables de zona horaria.TZ Controla la hora del sistema del container,GENERIC_TIMEZONE controla cómo n8n calcula el tiempo por sí mismo, Schedule Trigger reconoce esta última. Si solo configuras TZ, las tareas programadas siguen en UTC, lo que crees que es las 9 de la mañana se convierte en las 17:00 hora de Pekín. En los logs no quedará ni una sola anomalía de este tipo.
Tercer paso: revisar los logs, esperar a que arranque
docker logs -f n8n
El primer arranque ejecuta decenas de migraciones de base de datos,Starting migration ... 和 Finished migration ... alternándose, es normal. Espera hasta que aparezcan estas dos líneas:
Version: 2.43.7
Editor is now accessible via:
http://localhost:5678
Ese http://localhost:5678 es una dirección interna del container, no se puede abrir en el navegador. Lo que puedes abrir es http://服务器IP:5678, o en la máquina local http://127.0.0.1:5678. Esta línea ha engañado a mucha gente, incluido a mí la primera vez que lo ejecuté.
La versión 2.43.7 al arrancar también emite cinco advertencias de deprecation, sobre N8N_RUNNERS_MODE、N8N_UNVERIFIED_PACKAGES_ENABLED Estos valores por defecto habrá que cambiarlos más adelante. No afecta al uso, es para preparar el terreno para futuras versiones. Además hay otra línea Failed to start Python task runner in internal mode. because Python 3 is missing from this system.——en la image no está instalado Python, si solo usas el nodo Code de JS no tienes que preocuparte por ello.

Una vez creada la cuenta ya se entra. Este paso no tiene sentido si no se escribe en el volumen——abajo en la verificación se explica cómo confirmar que realmente se ha persistido en disco.
Cómo se considera que está bien instalado
Cuatro comprobaciones, todas en la terminal.
docker psEn STATUS estáUp, PORTS tiene mapeo, IMAGE es el tag que especificaste.curl -s http://127.0.0.1:5678/healthzDevuelve{"status":"ok"}. Esta interfaz solo indica que el proceso está vivo.docker exec n8n n8n --version回2.43.7, coincide con el tag que diste.docker restart n8n, espera una docena de segundos y vuelve a abrir la página, no debería pedirte crear la cuenta otra vez.
El punto 4 es el más fácil de pasar por alto y el más valioso. Verifica dos cosas a la vez: que el volumen está montado correctamente y que los datos realmente están fuera del container.

Cuando tomé esta captura eché un vistazo rápido a lo que había dentro del container .n8n, 5.5 MB, coincide con lo dicho arriba. Si tu du -sh sale con unos cientos de K, lo más probable es que los datos se hayan escrito en la capa escribible del container y el volumen no esté montado.
En qué archivo están realmente los datos
Una vez creado el volumen, Docker decide la ubicación real en el host; compruébalo con este comando:
docker volume inspect n8n_data
# [
# {
# "CreatedAt": "2026-11-02T09:28:41+08:00",
# "Driver": "local",
# "Mountpoint": "/var/lib/docker/volumes/n8n_data/_data",
# "Name": "n8n_data",
# "Scope": "local"
# }
# ]
«Mountpoint» es su ubicación real en el host. En esta máquina moví el directorio raíz de datos de Docker a /data/docker, por eso lo que se ve es /data/docker/volumes/n8n_data/_data; en una máquina con instalación por defecto es el /var/lib/docker/...de arriba. Toma como referencia la salida de tu propia máquina.
Dentro del container, así es como lo ve n8n:
docker exec n8n ls -la /home/node/.n8n
# -rw-r--r-- 1 node node 1519616 Nov 2 09:29 database.sqlite
# -rw-r--r-- 1 node node 32768 Nov 2 09:38 database.sqlite-shm
# -rw-r--r-- 1 node node 4136512 Nov 2 09:37 database.sqlite-wal
# -rw-r--r-- 1 node node 7972 Nov 2 09:37 n8nEventLog-1.log
# -rw-r--r-- 1 node node 526 Nov 2 09:38 n8nEventLog.log
Los workflows, los registros de ejecución y las credenciales cifradas están todos en database.sqlite . La clave de cifrado necesaria para descifrar las credenciales está en el mismo directorio, por defecto es el archivo config , generado automáticamente en el primer arranque.
Por eso, hacer backup de n8n son dos cosas: este directorio y el número de versión. Si solo respaldas el sqlite y no la clave, al restaurar en otra máquina las credenciales salen todas como texto corrupto.
Si quieres cambiarlo a un directorio del host que especifiques tú (por ejemplo /data/n8n), cambia el -v n8n_data:/home/node/.n8n Cambiar a -v /data/n8n:/home/node/.n8n es suficiente. Esto es un «bind mount»: el directorio queda bajo tu control, las copias de seguridad son más intuitivas, y el precio es que los permisos tienes que resolverlos tú mismo — el siguiente obstáculo es precisamente ese.
Seis errores que realmente encontrarás
1. Olvidar -v: borrar el container equivale a borrar la base de datos
Hice una comparación con dos containers, en la misma máquina y con la misma image: el que lleva -v n8n_data:/home/node/.n8n , tras reiniciar, la interfaz devuelve en «si mostrar la configuración inicial» un false; el otro, sin -v , la misma interfaz devuelve true— ha vuelto a ser una instancia vacía.
Todo el proceso no da error ni alerta. Simplemente un día abres y descubres que el workflow ya no está.
Cómo determinarlo:docker inspect n8n, sube y busca el fragmento "Mounts" ; si aparece "Destination": "/home/node/.n8n" significa que está montado; si todo el fragmento está vacío, entonces es peligroso.
2. Montar un directorio del host y recibir EACCES
Quieres usar bind mount, crear el directorio y montarlo directamente, así que:
Error: Failed to load command "start"
Error: EACCES: permission denied, open '/home/node/.n8n/config'
Antes seguía registrando los logs de migración con normalidad, pero de repente se quedó colgado aquí. Porque el n8n dentro de la image no es root, es un usuario con uid 1000 node(docker exec n8n id Se puede ver uid=1000(node)), y tu mkdir el directorio creado tiene como propietario root, 755, otros no pueden escribir en él.
Basta con cambiar el propietario:
chown -R 1000:1000 /data/n8n
Después de cambiarlo y volver a ejecutar, el mismo directorio, el mismo comando, 200, arrancó con normalidad, y los archivos realmente se escribieron en el directorio del host. En el host da igual quién sea el uid 1000, dentro del container lo que se reconoce es 1000.
3. port ocupado
docker: Error response from daemon: failed to set up container networking:
driver failed programming external connectivity on endpoint n8n
(...): failed to bind host port 0.0.0.0:5678/tcp: address already in use
Significa que el 5678 del host ya está siendo usado por alguien, no tiene nada que ver con el interior del container. Primero mira quién es:
ss -ltnp 'sport = :5678'
Lo habitual es que tu container n8n anterior siga ejecutándose,docker ps Se puede ver. O que el container antiguo se haya eliminado pero no del todo; lo más sencillo es cambiar de port y arrancarlo primero.
4. Acceder con IP + http, después de iniciar sesión vuelve a la página de login
La página abre, el usuario y la contraseña son correctos, al hacer clic en login no da error, y luego la página vuelve al formulario de login. Parece que la contraseña está mal, pero en realidad es un problema de cookie.
La cookie de login de n8n lleva Secure la marca (N8N_SECURE_COOKIE Por defecto es true), el navegador solo permite guardarla bajo HTTPS. Si accedes por http, el servidor igualmente devuelve 200, el navegador descarta directamente esa cookie, y la siguiente petición vuelve a quedarse sin estado de sesión.
Dos caminos: la forma correcta es poner delante una capa de Nginx con certificado; para depuración temporal en 内网穿透, añade -e N8N_SECURE_COOKIE=false, y acuérdate de borrar esta línea al terminar. No lo uses como configuración permanente — eso equivale a que tu usuario y contraseña viajen por un canal en texto plano.
5. Cierras la terminal y n8n se detiene con ella
Si lo ejecutaste según el comando docker run -it --rm del documento, Ctrl+C lo termina. No es un servicio en segundo plano, es un proceso en primer plano dentro de tu terminal.
补 -d Vuelve a ejecutarlo; si ya está corriendo,docker start n8n también puede recuperarlo, pero ese container ya lleva --rm Si fue eliminado, solo puedes volver a docker run— los datos están en el volume, siguen ahí.
6. Usaste latest y un día el comportamiento cambió
Sin errores, sin alertas, solo que tras reiniciar un día los valores por defecto de los nodos, la interfaz o incluso el nombre de algún parámetro cambiaron. La causa es que descargaste una versión nueva.
Fija el número de versión y trata la actualización como una tarea seria: primero haz backup del volume, luego cambia el tag, y tras arrancar ejecuta dos workflows clave para ver los resultados. La actualización en sí no tiene ninguna dificultad técnica, el problema está todo en «no saber qué cambió».
Varios puntos de seguridad relacionados con n8n
No expongas el 5678 directamente a la red pública.n8n tiene página de inicio de sesión, pero es una aplicación autoalojada; más allá del login no hay protección adicional, y los escáneres buscan este tipo de puertos todos los días. Ponerlo en 0.0.0.0 sin reverse proxy ni HTTPS es como colgar la llave de casa en la puerta. La configuración que usé en mis pruebas -p 127.0.0.1:5678:5678 ya bloquea el exterior.
docker El grupo equivale a root.Quien pueda / montar algo dentro del container, puede modificar cualquier archivo del host. Piensa bien esto antes de dar permisos a un compañero.
Trata los volúmenes como secretos.Ahí dentro database.sqlite está el texto cifrado de todas las credenciales, y en el mismo directorio está la clave de descifrado. Quien se lleve ambas cosas, todos los tokens de tus cuentas de terceros quedarán en texto plano. Dónde poner el backup importa más que el backup mismo.
No escribas contraseñas en la línea de comandos.docker run -e DB_PASSWORD=xxx Quedarán en docker inspect la salida de y cualquiera que lo ejecute podrá verlas. Para pasar valores sensibles usa un archivo env, o las variables con sufijo _FILE .
Resumen
Con cuatro palabras basta para arrancar: la image es el paquete, el container es el paquete en ejecución, el volume es el terreno fuera del paquete, y el port es el número de la puerta.
El único lugar donde realmente puede salir mal al instalar n8n es uno: el volumen no está montado. No da error, y no lo descubrirás de inmediato; cuando lo descubras, el workflow ya no estará. Así que lo primero tras la instalación es docker restart una vez, para ver si los datos siguen ahí.
El resto es cuestión de soltura. Con la práctica descubrirás que la mayor ventaja de Docker no es «multiplataforma», sino «si algo sale mal, se borra y se vuelve a empezar»: los datos están en el volumen, y el container se puede tirar en cualquier momento.
La entrada anterior escómo investigar errores de arranque de n8n y ocupación de port, ahí se trata el caso de que no arranca. El índice de toda la serie está enaquí, y los de tipo fallo los tengo aparte en la página故障排查.
Referencias
- Install with Docker: los comandos oficiales,
docker runla explicación del volumen, y los pasos para actualizar la imagedocker volume create、/home/node/.n8n - Instalar usando Docker Compose: la configuración de la versión compose,
5678:5678ese comentario dice «el único puerto que debería estar expuesto al exterior» - Variables de entorno de Deployment:
N8N_PORTpor defecto 5678,N8N_LISTEN_ADDRESSpor defecto::、N8N_USER_FOLDER与N8N_ENCRYPTION_KEY - Variables de entorno de Security:
N8N_SECURE_COOKIEpor defectotrue、N8N_ENFORCE_SETTINGS_FILE_PERMISSIONSpor defectofalse - Volúmenes de Docker: el volumen existe en el host
/var/lib/docker/volumes/<名字>/_data, y su diferencia con el bind mount - lista de tags de n8nio/n8n: un tag por versión, se puede consultar el digest de la imagen y el tamaño comprimido
- Instalar Docker Engine en UbuntuPasos completos con el repositorio oficial de apt, si no quieres usar el script todo en uno, sigue esta vía.
Última actualización: 2 de noviembre de 2026, usando n8n 2.43.7.

