Cómo instalar n8n con Docker en un VPS Ubuntu 24.04
Instalar n8n en un VPS proporciona control sobre la infraestructura y los datos, pero también obliga a gestionar actualizaciones, copias de seguridad y seguridad. Esta guía explica una arquitectura razonable para Ubuntu 24.04 utilizando Docker, PostgreSQL y un proxy inverso.
Resumen rápido
- n8n y PostgreSQL se ejecutan en contenedores separados.
- PostgreSQL no publica ningún puerto en Internet.
- n8n tampoco publica directamente el puerto 5678.
- Caddy es el único servicio que recibe tráfico HTTPS.
- Los secretos se almacenan en un archivo .env con permisos restrictivos.
Arquitectura recomendada
El objetivo es separar la aplicación, la base de datos y el proxy. n8n comparte una red privada con PostgreSQL y otra red de entrada con Caddy. De esta manera, la base de datos solo es accesible desde el contenedor de n8n.
El dominio público apunta al VPS y Cloudflare puede actuar como proxy. Caddy termina la conexión HTTPS y reenvía internamente las solicitudes a n8n. El puerto 5678 aparece dentro de Docker, pero no debe estar publicado como 0.0.0.0:5678 en el servidor.
- Internet y Cloudflare llegan únicamente al puerto 443 de Caddy.
- Caddy alcanza n8n mediante una red Docker compartida.
- n8n alcanza PostgreSQL mediante una red interna diferente.
- Los volúmenes conservan la base de datos y la configuración de n8n.
Preparar el servidor
Antes de comenzar necesitas un VPS actualizado, un dominio o subdominio y Docker con el complemento Compose. Comprueba que el dominio resuelve hacia la IP pública correcta y que el firewall permite HTTPS.
Crea una carpeta independiente para el proyecto. Utilizar rutas previsibles simplifica las copias de seguridad y evita mezclar archivos de WordPress con los de n8n.
sudo mkdir -p /opt/breachreel/n8n
cd /opt/breachreel/n8n
sudo chmod 750 /opt/breachreel/n8nCrear secretos y variables
Genera contraseñas largas para PostgreSQL y una clave de cifrado estable para n8n. La clave de cifrado protege las credenciales almacenadas; si la pierdes, una copia de la base de datos puede dejar de ser útil para recuperar esos secretos.
El archivo .env no debe enviarse a repositorios ni mostrarse en capturas. Dale permisos 600 y guarda una copia cifrada fuera del VPS.
umask 077
POSTGRES_PASSWORD="$(openssl rand -hex 32)"
N8N_ENCRYPTION_KEY="$(openssl rand -hex 32)"
printf 'POSTGRES_PASSWORD=%snN8N_ENCRYPTION_KEY=%sn'
"$POSTGRES_PASSWORD" "$N8N_ENCRYPTION_KEY" > .env
chmod 600 .envDefinir los servicios con Docker Compose
El siguiente ejemplo muestra el patrón esencial. Sustituye el dominio y revisa las versiones antes de utilizarlo. En producción es preferible fijar versiones concretas y actualizar de forma controlada en lugar de depender indefinidamente de latest.
La red frontend debe existir también en el proyecto de Caddy. La red database se marca como interna para reducir su exposición.
services:
postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_DB: n8n
POSTGRES_USER: n8n
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- database
healthcheck:
test: ["CMD-SHELL", "pg_isready -U n8n -d n8n"]
interval: 10s
timeout: 5s
retries: 5
n8n:
image: docker.n8n.io/n8nio/n8n:latest
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
environment:
DB_TYPE: postgresdb
DB_POSTGRESDB_HOST: postgres
DB_POSTGRESDB_DATABASE: n8n
DB_POSTGRESDB_USER: n8n
DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}
N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
N8N_HOST: n8n.tudominio.com
N8N_PROTOCOL: https
WEBHOOK_URL: https://n8n.tudominio.com/
N8N_PROXY_HOPS: 1
GENERIC_TIMEZONE: Europe/Madrid
volumes:
- n8n_data:/home/node/.n8n
networks:
- database
- frontend
networks:
database:
internal: true
frontend:
external: true
volumes:
postgres_data:
n8n_data:Configurar Caddy y arrancar
Caddy debe estar unido a la misma red frontend y resolver el servicio de n8n por su alias dentro de Docker. No es necesario publicar 5678 en el host.
Valida primero la configuración y después inicia los servicios. Revisa que PostgreSQL esté healthy y que n8n permanezca estable antes de probar el dominio.
n8n.tudominio.com {
encode zstd gzip
reverse_proxy n8n:5678
}
# Desde la carpeta de n8n
docker compose config --quiet
docker compose up -d
docker compose psComprobaciones y mantenimiento
Comprueba con docker compose ps que solo Caddy publique 443. Los textos 5678/tcp y 5432/tcp indican puertos internos declarados por las imágenes, no que estén abiertos en la IP pública.
Antes de actualizar, guarda copias de PostgreSQL, del volumen de n8n, del archivo Compose y de la clave de cifrado. La documentación de n8n recomienda mantener la instalación al día y revisar los cambios antes de saltos importantes.
- Verifica HTTPS y la URL de producción de los webhooks.
- Prueba una restauración en un entorno separado.
- Revisa regularmente los registros y ejecuciones fallidas.
- No expongas el panel sin autenticación y HTTPS.
- No publiques PostgreSQL ni 5678 directamente.
Fuentes oficiales
- Documentación oficial: instalar n8n con Docker
- Configurar webhooks detrás de un proxy
- Actualizar una instalación self-hosted
Continúa aprendiendo
Consulta la guía introductoria de BreachReel o descubre la formación estructurada para avanzar desde los fundamentos hasta automatizaciones completas.