Servidor propio con Docker

Por: Artiko
nodself-hosteddockerdocker-composehttpscaddyssh

Servidor propio con Docker

Objetivos

  • Instalar el stack de servidor de Nod con Docker Compose.
  • Abrir el servidor sin dominio mediante un túnel SSH.
  • Publicarlo con HTTPS usando el perfil incluido o un proxy propio.
  • Conectar la app de escritorio, las apps y los canales al servidor.
  • Usar un Mac mini como servidor.

Un servidor propio mantiene un asistente en marcha para tus clientes web y de escritorio. Sigue trabajando con los clientes cerrados, que es lo que hace falta para que las programaciones corran con el portátil apagado. Un servidor pertenece a una sola persona: no hay modo multiusuario.


Requisitos

RequisitoDetalle
SistemaLinux AMD64 o ARM64, o un Mac con Docker Desktop
Recursos para empezar2 CPU, 8 GB de RAM y 50 GB de disco
SoftwareDocker Engine 25 o posterior con Compose v2, OpenSSL y sha256sum o shasum. Para compilar desde código, también Git
Acceso remotoUn túnel SSH, o un dominio con los puertos 80 y 443 abiertos para HTTPS

Qué corre en el servidor

flowchart LR
    Cliente["App web o de escritorio"] --> Proxy["Proxy HTTPS"]
    Proxy --> Srv["Servidor de Nod"]
    Canales["Telegram o WhatsApp"] --> Srv
    Srv --> DB[("PostgreSQL")]
    Srv --> Rt["Conexión Docker restringida"]
    Rt --> WS["Contenedor del workspace"]
    Rt --> BR["Contenedor del navegador"]
  • La base de datos, el workspace y el navegador quedan privados.
  • Las claves de modelos y las credenciales guardadas se quedan en el servidor, fuera de los contenedores del workspace y del navegador.
  • El workspace usa un contenedor de firewall aparte. Bloquea destinos IPv4 privados y reservados, incluidos los servicios de metadatos de nube, y el tráfico IPv6 externo. El workspace arranca solo cuando ese firewall está listo. Sus consultas DNS usan los resolvedores públicos 1.1.1.1 y 8.8.8.8.
  • Los datos persistentes viven en volúmenes con nombre. Recrear un contenedor los conserva. Borrar los volúmenes elimina tus datos.

Opción A: compilar desde código fuente

git clone https://github.com/n8n-io/nod.git
cd nod/deployment/self-host
sh setup.sh
docker compose up -d --build --wait

setup.sh genera el archivo .env del stack con tres secretos: el token de acceso del servidor (NOD_AUTH_TOKEN), la clave de Vault (NOD_VAULT_KEY) y la contraseña de la base de datos (NOD_POSTGRES_PASSWORD). Si el .env ya existe, lo conserva.

Después abre http://localhost:4310 y pega el valor de NOD_AUTH_TOKEN del .env en el formulario de acceso.

El token da acceso total al asistente. Mantén .env privado e inclúyelo en tu respaldo. NOD_AUTH_TOKEN y NOD_VAULT_KEY son secretos distintos y conviene guardarlos por separado.

Opción B: bundle precompilado

Las releases incluyen bundles con nombre server-<commit> para amd64 y arm64. La documentación indica que son releases privadas y que hace falta acceso al repositorio para descargar los archivos.

sha256sum -c nod-server-linux-<architecture>-<commit>.tar.gz.sha256
tar -xzf nod-server-linux-<architecture>-<commit>.tar.gz
cd nod-server-linux-<architecture>
sh install.sh

En macOS, usa shasum -a 256 -c en lugar de sha256sum -c. El instalador comprueba las imágenes y arranca sin compilar.


Abrir un servidor remoto sin dominio

El stack escucha en la interfaz loopback del servidor (NOD_BIND_ADDRESS vale 127.0.0.1 por defecto). Para abrirlo desde tu equipo sin publicar nada, usa un túnel SSH:

ssh -L 4310:127.0.0.1:4310 <user>@<server-address>

Mantén la conexión abierta y visita http://localhost:4310.

sequenceDiagram
    actor Tu as Tú
    participant L as Tu equipo
    participant S as Servidor
    Tu->>L: ssh -L 4310:127.0.0.1:4310
    L->>S: Túnel cifrado
    Tu->>L: Abre http://localhost:4310
    L->>S: La petición viaja por el túnel
    S-->>Tu: Formulario de acceso con NOD_AUTH_TOKEN

Añadir HTTPS público

Para publicar Nod con un dominio, define el origen público en .env:

NOD_PUBLIC_URL=https://nod.example.com

Y arranca con el perfil HTTPS. Con un bundle:

sh install.sh --https

Con una instalación desde código:

docker compose --profile https up -d --build --wait

Caddy obtiene y renueva el certificado. El perfil HTTPS usa los puertos 80 y 443 del host. Si hay varias instalaciones HTTPS en la misma máquina, hace falta un proxy inverso compartido.

Reglas de NOD_PUBLIC_URL:

  • Es el origen exacto desde el que abres Nod: esquema, host y puerto.
  • No lleva ruta, query, fragmento ni credenciales de usuario.
  • Un origen remoto exige HTTPS y NOD_AUTH_TOKEN. Los orígenes loopback pueden usar HTTP.
  • Definir solo esta variable no crea un proxy ni un certificado.

Usar un proxy existente

En lugar del perfil HTTPS puedes usar tu propio proxy inverso, incluso con un puerto propio, por ejemplo https://nod.example.com:8443.

  • Reenvía las peticiones al puerto loopback 4310 del stack, o al que definas en PORT.
  • Conserva la cabecera Host pública y admite WebSockets y respuestas en streaming.
  • Define NOD_PUBLIC_URL con ese origen HTTPS exacto. Nod no confía en las cabeceras reenviadas para decidir qué origen está permitido.
  • Mantén privado el puerto del backend. No expongas PostgreSQL, el navegador, el workspace ni la conexión de Docker.
  • Nod da cinco minutos para recibir el cuerpo de una petición. Ese límite no afecta a la duración de las respuestas del asistente ni a los flujos de eventos.

Conectar la app de escritorio

  1. En el primer arranque de la app, elige Connect to a server. Más adelante, abre Replay onboarding… en el menú Nod y elige Connect to a server.
  2. Escribe la dirección del servidor y el valor de NOD_AUTH_TOKEN. Usa la dirección HTTPS, o http://localhost:4310 mientras el túnel SSH está abierto.
  3. La app verifica el servidor antes de guardar el token en el almacenamiento seguro del sistema operativo. Reinicia en el asistente remoto sin arrancar un runtime local.

Algunos detalles:

  • El asistente local de la app es independiente. Conectarse a un servidor no migra sus datos. Para volver a él: Replay onboarding… → Change server → Use this computer.
  • Las conexiones de modelos y de apps corren en el servidor. Usa direcciones que el servidor pueda alcanzar: dentro de una instalación Docker, localhost es el contenedor del servidor, no el equipo donde corre el cliente.
  • Como el servidor es dueño de las cuentas conectadas, otro dispositivo llega al mismo asistente sin volver a conectarlas.

Conectar apps y canales en el servidor

Apps. Abre Apps y selecciona Connect. Para las apps conectadas mediante Composio, Nod abre una página de inicio de sesión en tu NOD_PUBLIC_URL. Selecciona Continue para iniciar sesión en la ventana que se abre y deja abierta la primera página hasta que termine. Si el navegador bloquea la ventana, permite las ventanas emergentes para Nod.

La página de inicio y su callback usan la dirección y el puerto normales de Nod, así que el túnel SSH o el proxy HTTPS que usas para abrir Nod también sirve para esto. Después de cambiar la dirección o reiniciar el servidor, inicia una conexión nueva desde Apps: las páginas antiguas no pueden reanudarla.

Canales. Abre Channels y sigue el capítulo 13.

CanalNecesita dirección pública
Telegram con pollingNo, solo salida a internet
WhatsApp por código QRNo, solo salida a internet
Telegram con webhookSí, HTTPS público
WhatsApp Cloud API de MetaSí, HTTPS público

Los pasos privados de inicio de sesión y de pago se quedan en la app web o de escritorio.


Mantenerlo en marcha

Los contenedores se reinician cuando arranca Docker. Antes de la primera actualización, sigue el procedimiento de respaldo del capítulo 14. Los comandos de uso diario son estos:

docker compose ps
docker compose logs --tail 100 server
docker compose stop
docker compose up -d --wait

Con el perfil HTTPS, añade --profile https a los comandos de arranque, parada y estado.

No borres los volúmenes. docker compose down --volumes elimina los datos de la instalación.


Un Mac mini como servidor

Un Mac mini puede ejecutar el mismo stack que un servidor Linux. No es la app de escritorio: es el servidor con Docker.

  1. Instala Docker Desktop para Mac, en la versión de tu procesador.
  2. Asigna a Docker al menos 8 GB de memoria y 50 GB de disco, dejando capacidad para macOS.
  3. En Docker Desktop, activa Start Docker Desktop when you sign in to your computer. Docker arranca después de iniciar sesión, no antes.
  4. Mantén el Mac despierto. Tras un corte de luz o un reinicio, inicia sesión y confirma que Docker y Nod arrancaron.
  5. Sigue este capítulo usando una carpeta dedicada para la instalación.

Los contenedores Linux corren en la máquina virtual de Docker: Apple silicon usa el bundle Linux ARM64 e Intel el Linux AMD64.

Acceso desde otros dispositivos:

TipoCómo
PúblicoDominio y HTTPS. El router debe reenviar los puertos 80 y 443 al Mac. Algunas conexiones domésticas bloquean el tráfico entrante o usan CGNAT
Privado, opción ATúnel SSH al Mac, directo o sobre una VPN
Privado, opción BProxy inverso HTTPS accesible por VPN, con NOD_PUBLIC_URL igual al origen exacto de ese proxy

Una VPN por sí sola no expone el puerto loopback del stack ni aporta el HTTPS que exige un origen remoto. La autenticación por token se mantiene también en redes privadas.


Actividad

  1. Instala el stack con la opción A en una máquina con Docker.
  2. Abre Nod por túnel SSH y entra con el token.
  3. Ejecuta docker compose ps y relaciona cada contenedor con el diagrama del capítulo.
  4. Si tienes un dominio, define NOD_PUBLIC_URL y arranca con el perfil HTTPS.
  5. Conecta la app de escritorio al servidor y comprueba que ves la misma conversación que en la web.

Autoevaluación

1. ¿Qué genera setup.sh?

El archivo .env del stack, con el token de acceso del servidor, la clave de Vault y la contraseña de la base de datos.

2. ¿Cómo se abre un servidor remoto que no tiene dominio?

Con un túnel SSH: ssh -L 4310:127.0.0.1:4310 <user>@<server-address> y luego http://localhost:4310.

3. ¿Qué exige un NOD_PUBLIC_URL remoto?

HTTPS y NOD_AUTH_TOKEN. Debe ser el origen exacto, sin ruta, query, fragmento ni credenciales.

4. ¿Qué pasa con los datos locales de la app de escritorio al conectarla a un servidor?

No se migran. El asistente local queda aparte y se puede volver a él con Use this computer.

5. ¿Qué canales funcionan sin dirección pública?

Telegram con polling y WhatsApp por código QR, porque usan conexiones salientes.


Lista de control

  • El stack arranca con docker compose up -d --build --wait.
  • Guardé .env en un lugar privado y dentro de mi respaldo.
  • Puedo abrir Nod por túnel SSH o por HTTPS.
  • NOD_PUBLIC_URL coincide con la dirección exacta que abro.
  • La app de escritorio está conectada al servidor.
  • No expongo PostgreSQL, el workspace, el navegador ni el socket de Docker.

Anterior: Instalar desde código fuente · Siguiente: Primera conversación