En este segundo artículo vamos a explicar en qué consiste la configuración de la base de datos para la herramienta n8n y cuáles son sus diferentes opciones.

A modo de recordatorio pongo los enlaces a los artículos que se irán relacionando :
- "Primeros pasos con n8n (Parte 1)" : Artículo de introducción a la herramienta n8n donde se explicarán más ciertos detalles técnicos de la herramienta y ciertos conceptos necesarios para explotar el máximo su uso.
- "Acelerando los desarrollos con contenedores : n8n": Artículo de soporte que ayudará a desplegar la herramienta en local mediante Docker y que servirá de base para la realización de los siguientes artículos.
- "Ejemplo de n8n: Uso del nodo code": Artículo de soporte que se utilizará para implementar un ejemplo de workflow sin integraciones externas, para explicar el nodo code y para usarlo como base de ejemplo para otros tutoriales.
- "Primeros pasos con n8n (Parte 2) : Uso de Base de Datos": Artículo de la herramienta n8n donde se explicarán las diferentes configuraciones de base de datos que se pueden tener y su integración. Este artículo 😃.
Este es el índice que se va a utilizar para estructurar este artículo
- 1. Introducción
- 2. Stack Tecnológico
- 3. Ejemplos de Uso
- 4. Conclusiones
1. Introducción
En este apartado se tratarán los siguiente puntos :
- 1.1. ¿Por qué es necesario usar una base de datos en n8n?
- 1.2. Tipos de configuración de base de datos en n8n
1.1. ¿Por qué es necesario usar una base de datos en n8n?
La herramienta n8n necesita usar la base de datos para gestionar la información clave necesaria para su correcto funcionamiento.
Alguna la información almacenada es la siguiente:
- Flujos de trabajo / Workflows: Almacena la estructura, configuraciones y conexiones entre nodos. En definitiva, permite recordar los flujos de trabajo creados.
- Credenciales / Credentials: Almacena toda la información privada necesaria y utilizada en algunos de los componentes. Se trata de información tipo usuarios, passwords, tokens, etc. Así que es información muy importante y que se guarda cifrada.
- Ejecuciones /Executions: Almacena el registro de ejecución de cada flujo de trabajo. Para ello registra aspectos como tiempos, resultado de las ejecuciones, errores, datos procesados, etc.
- Control de versiones y estado: Almacena la situación de activación de los flujos de trabajo y aspectos como versiones anteriores
- Gestión de usuario y permisos: Almacena información sobre usuarios, roles y permisos
Como podéis ver se necesita una base de datos para guardar muchas cosas 😄
1.2. Tipos de configuración de bases de datos en n8n
Actualmente existen 3 tipos de configuración
- Configuración con SQLite
- Configuración con PostgreSQL
- Configuración "SIN" Base de datos
Configuración con SQLite
SQLite es la base de datos relacional embebida que usa n8n por defecto en instalaciones básicas.
Consideraciones:
- Es una base de datos ligera
- No tiene todas las funcionalidades de una base de datos "típica"
- No requiere una instalación adicional (viene con la propia herramienta)
- Fácil de configurar
- Consumo de recursos mínimo
- No se aconseja su uso en entornos productivos
- Muy útil para pruebas, entornos locales y proyectos pequeños
- Pocos usuarios
- Pocos flujos de trabajo
- Uso con proyectos no muy críticos
- Autocontenida
- Cuando se arranca en este modo se crea un fichero en el directorio de configuración de n8n con el nombre: database.sqlite
- Todo esta en un fichero
- Este fichero facilita la portabilidad y los bakups
- Riesgo de que si se daña el fichero se pierda todo
- Difícil de Escalar
- Con muchos datos la base de datos se vuelve más lenta
- No gestiona bien las conexiones concurrentes
Configuración con PostgreSQL
PostgreSQL es una base de datos relacional avanzada que está muy consolidada en el mercado y es muy popular
Consideraciones:
- Es una base de datos más compleja que la anterior
- Consumo de más recursos
- Aconsejada para entornos productivos
- Añade una capa más de instalación, configuración, gestión y mantenimiento a los proyectos
- Muy útil para proyectos serios y para empresas
- Muchos usuarios simultáneos
- Muchos flujos de trabajo activos
- Uso con proyectos críticos
- Facilita el manejo de grandes volúmenes de información
- Proporciona características de escalabilidad, seguridad, recuperación ante fallos, copias de seguridad, replicación, concurrencia, etc.
- Facilita la integración con herramientas empresariales
Configuración "SIN" Base de datos
La herramienta n8n no puede funcionar sin utilizar una de las 2 bases de datos anteriores.
La herramienta utiliza una base de datos en memoria SQLite que se perderá al cerrar la aplicación si no se establece un volumen de persistencia por configuración.
Por lo que interesa configurar la base de datos desde el primer momento.
2. Stack Tecnológico
Este es el stack tecnológico elegido para implementar la funcionalidad "n8n":
- Docker - Tecnología de Contenedores/Containers
- Docker Hub - Repositorio de Docker Público donde se ubican las imágenes oficiales
- n8n - Herramienta de automatización de procesos + Agentes IA
- PostgreSQL - Base de Datos relacional (Versión 16)
3. Ejemplos de Uso
Para enseñar a utilizarlo y así practicar se ha habilitado un repositorio, este repositorio se reutilizará para otros artículos de la serie "Primeros pasos con n8n".
3.1. Uso de SQLite
Para llevar a cabo este ejemplo podemos hacer uso del ejemplo que utilizamos en el artículo "Acelerando los desarrollos con contenedores : n8n"
Este ejemplo utiliza SQLite por defecto y tiene establecido un volumen local con el directorio de configuración de n8n dentro del contenedor por lo que se puede verificar que se está usando esta base de datos.

Este ejemplo es el que se utiliza en el artículo "Acelerando los desarrollos con contenedores : n8n"
3.2. Uso con PostgreSQL
La parte que tiene que ver con este ejemplo de uso se encuentra en el apartado del repositorio example/database
Se van a seguir una serie de pasos:
- 3.2.1. Preparar la base de datos PostgreSQL (Opcional)
- 3.2.2. Integración n8n + PostgreSQL
3.2.1. Preparar la base de datos PostgreSQL (Opcional)
Este apartado es opcional. Para asegurarnos de que la integración se realiza con pocos problemas. Trataremos de hacer primero un análisis básico de la infraestructura de PostgreSQL que utilizaremos en Docker y nos aseguraremos de que funciona correctamente.
Para su realización seguiremos una serie de pasos:
- Paso 1: Creación de un fichero .env
- Paso 2: Creación de un fichero de inicialización de base de datos "init-data.sh"
- Paso 3: Creación del fichero Docker Compose
- Paso 4: Verificación de la herramienta PostgreSQL
Paso 1: Creación de un fichero .env
Crearemos un fichero .env con las variables de entorno que usaremos para establecer la configuración de la base de datos PostgreSQL.
Se ha facilitado un fichero .env de ejemplo que lleva por nombre .env.example. Para hacerlo funcionar bastaría con crear una copia del fichero en esta ubicación y eliminar la parte del ".env"
Se ha habilitado el fichero en el repositorio: .env.example
- Se aconseja crear una copia y quitar la extensión ".example"
### --- POSTGRESQL SETTINGS ---
DB_POSTGRES_USER=admin
DB_POSTGRES_PASSWORD=admin
DB_POSTGRES_DB=n8ndb
DB_POSTGRES_NON_ROOT_USER=n8n
DB_POSTGRES_NON_ROOT_PASSWORD=n8n
Estas variables de entorno están establecidas de forma custom a nivel de nombre por mí y no por el fabricante de PostgreSQL (variables de entorno). A nivel de comportamiento funcional serán iguales que las del fabricante. Se ha pensado así para que puedan ser compartidas por los diferentes contenedores ya que pueden ser referenciados con otros valores a nivel de nombre.
Por ejemplo: DB_POSTGRES_DB
- La variable de entorno referenciada desde el contenedor de postgres será POSTGRES_DB
- La variable de entorno referenciada desde el contenedor de n8n será DB_POSTGRESDB_DATABASE
Los valores que aquí aparecen pueden ser cambiados sin problemas.
Paso 2: Creación de un fichero de inicialización de base de datos "init-data.sh"
Crearemos un fichero de script "init-data.sh" ejecutable con los valores o configuración que queremos que tenga la base de datos en su inicio.
Consideraciones:
- Se ejecuta la primera vez que se inicia el contenedor con datos vacíos
- Se utiliza para cargar configuración inicial o bien carga de datos de prueba
- Compatible con varios motores de base de datos en Docker
Este script de shell se suele colocar dentro de docker-entrypoint-initdb.d/ y se utiliza para ejecutar comandos personalizados durante la inicialización del contenedor.
Se ha habilitado el fichero en el repositorio: init-data.sh
#!/bin/bash
set -e;
if [ -n "${POSTGRES_NON_ROOT_USER:-}" ] && [ -n "${POSTGRES_NON_ROOT_PASSWORD:-}" ]; then
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
CREATE USER ${POSTGRES_NON_ROOT_USER} WITH PASSWORD '${POSTGRES_NON_ROOT_PASSWORD}';
GRANT ALL PRIVILEGES ON DATABASE ${POSTGRES_DB} TO ${POSTGRES_NON_ROOT_USER};
GRANT CREATE ON SCHEMA public TO ${POSTGRES_NON_ROOT_USER};
EOSQL
else
echo "ERROR: No Environment variables"
fi
Como este script se ejecuta dentro del contenedor deberá tener disponible las variables de entorno utilizadas dentro del propio contenedor. Se tratarán de pasar desde el propio fichero docker-compose
Con este script se pretende crear un usuario con permisos de administrador pero diferente del usuario tipo admin principal de la base de datos. Con ello, crearemos un usuario de servicio para n8n.
Los valores de las variables de entorno vendrán dados por el fichero .env anterior.
Importante: Este fichero debe de tener permisos de ejecución.
Paso 3: Creación del fichero Docker Compose
Este ejemplo esta descrito en el fichero : DB-docker-compose-prepare-db.yml
Crearemos un fichero Docker Compose que se componga de los siguientes elementos:
Base de datos Postgresql
Base de datos relacional que utilizaremos
- Se establece la imagen con una versión establecida: postgres:16
- Esta es la versión con la que se configuró la imagen
- Se aconseja estar actualizado a nivel de la herramienta
- Se define el nombre del contenedor como: postgres
- Se define la política de restart
- Se define la red en la que se ubicará: demo
- En este caso se trata de una red privada
- Se establecen algunas variables de entorno que ayudarán a la configuración de la herramienta
- En este caso se define datos de autenticación del usuario tipo admin, nombre del esquema de base de datos y otra información
- Se define el puerto:
- 5432 para conexión de base de datos
- Se definen los volúmenes del contenedor:
- Se establece la referencia del fichero de inicialización de base de datos externo con su valor interno dentro del contenedor : init-data.sh
- Se mapea el directorio de configuración de postgres
- Control de healthcheck para saber si está disponible
Pgadmin
Consola de administración web de la base de datos PostgresSQL
- Se establece la imagen con una versión establecida: dpage/pgadmin4:9.0.0
- Esta es la versión con la que configuró la imagen
- Se aconseja estar actualizado a nivel de la herramienta
- Se define el nombre del contenedor como: pgadmin
- Se define la política de restart
- Se define la red en la que se ubicará : demo
- En este caso se trata de una red privada
- Se establecen algunas variables de entorno que ayudarán a la configuración de la herramienta
- Configuración de la propia herramienta a nivel de usuario admin
- Se define el puerto:
- 5050 para las peticiones HTTP de la interfaz web
- Se definen los volúmenes del contenedor:
- Se mapea el directorio de configuración de pgadmin
Ejemplo de fichero DB-docker-compose-prepare-db.yml
# Use Case: Prepare PostgreSQL
services:
# Project URL: https://github.com/postgres/postgres
# Docs URL: https://www.postgresql.org/docs/16/index.html
postgres:
image: postgres:16
container_name: "postgres"
restart: always
networks: ['demo']
environment:
# *** Settings ***
- POSTGRES_USER=${DB_POSTGRES_USER}
- POSTGRES_PASSWORD=${DB_POSTGRES_PASSWORD}
- POSTGRES_DB=${DB_POSTGRES_DB}
- POSTGRES_NON_ROOT_USER=${DB_POSTGRES_NON_ROOT_USER}
- POSTGRES_NON_ROOT_PASSWORD=${DB_POSTGRES_NON_ROOT_PASSWORD}
ports:
- 5432:5432
volumes:
# *** Database Initializer ***
- ./init-data.sh:/docker-entrypoint-initdb.d/init-data.sh
# *** Volume configuration ***
- ./db-data:/var/lib/postgresql/data
healthcheck:
test: ['CMD-SHELL', 'pg_isready -h localhost -U ${DB_POSTGRES_NON_ROOT_USER} -d ${DB_POSTGRES_DB}']
interval: 5s
timeout: 5s
retries: 10
# Project URL: https://github.com/pgadmin-org/pgadmin4
# Docs URL: https://www.pgadmin.org/docs/pgadmin4/8.14/index.html
pgadmin:
image: dpage/pgadmin4:9.0.0
#image: dpage/pgadmin4:8.14.0
container_name: "pgadmin"
restart: always
networks: ['demo']
environment:
# *** Settings ***
- PGADMIN_LISTEN_PORT=80
# *** Users ***
- PGADMIN_DEFAULT_EMAIL=admin@acme.com
- PGADMIN_DEFAULT_PASSWORD=admin
depends_on:
- postgres
ports:
- 5050:80
volumes:
- ./pgadmin-data:/var/lib/pgadmin
volumes:
db-data:
pgadmin-data:
networks:
demo:
driver: bridge
Para ver como lanzarlo, ver fichero README dentro del de la sección "database".
Este ejemplo se puede lanzar individualmente desde Docker Compose o bien se ha montado una herramienta de gestión rápida sobre tecnología Makefile que ayudará en la gestión de la plataforma formativa de n8n.
- Esta aplicación se explicará en el README principal del repositorio
Paso 4: Verificación de la herramienta PostgreSQL
Verificaremos que podemos acceder a la base de datos desde pgadmin
Pasos a seguir:
- Verificar que se encuentran disponibles los 2 contenedores
- pgadmin
- postgres
- Acceder a la plataforma de pgadmin: http://localhost:5050

- Autenticarse con el usuario admin creado para su gestión

- Añadir un nuevo servidor

- Establecer el nombre con el que se identificará al servidor. Por ejemplo: postgres
- Acceder a la pestaña de conexiones

Establecer el
- Nombre del host con el nombre del contenedor: postgres
- Nombre del usuario: admin
- Password del usuario: admin
- No cambiar la base de datos a la que apunta (en este caso postgres)
- Verificar que se ha creado servidor

Se mostrará información de monitorización de la herramienta
Con este usuario se debería de tener acceso a todos los esquemas 😃
3.2.2. Integración n8n + PostgreSQL
Este es el "plato fuerte" de este tutorial, lo que vamos a hacer es configurar la integración entre estos dos productos.
Para ello utilizaremos la infraestructura de base de datos anteriormente explicada para PostgreSQL y la instalación de n8n del artículo "Acelerando los desarrollos con contenedores : n8n" pero con una pequeña adaptación en sus variables de entorno.
Se puede acceder a la documentación donde se habla de esta integración mediante variables de entorno de base de datos en n8n.
Para su realización seguiremos una serie de pasos:
- Paso 1: Creación de un fichero .env
- Paso 2: Creación del fichero Docker Compose
- Paso 3: Verificación de la herramienta PostgreSQL
- Paso 4: Verificación de la herramienta n8n
Paso 1: Creación de un fichero .env
Haremos uso del fichero creado en el apartado 3.2.1.
Paso 2: Creación del fichero Docker Compose
El fichero Docker compose quedaría de la siguiente forma
# Use Case: Database Integration
services:
# Project URL: https://github.com/postgres/postgres
# Docs URL: https://www.postgresql.org/docs/16/index.html
postgres:
image: postgres:16
container_name: "postgres"
restart: always
networks: ['demo']
environment:
# *** Settings ***
- POSTGRES_USER=${DB_POSTGRES_USER}
- POSTGRES_PASSWORD=${DB_POSTGRES_PASSWORD}
- POSTGRES_DB=${DB_POSTGRES_DB}
- POSTGRES_NON_ROOT_USER=${DB_POSTGRES_NON_ROOT_USER}
- POSTGRES_NON_ROOT_PASSWORD=${DB_POSTGRES_NON_ROOT_PASSWORD}
ports:
- 5432:5432
volumes:
# *** Database Initializer ***
- ./init-data.sh:/docker-entrypoint-initdb.d/init-data.sh
# *** Volume configuration ***
- ./db-data:/var/lib/postgresql/data
healthcheck:
test: ['CMD-SHELL', 'pg_isready -h localhost -U ${DB_POSTGRES_NON_ROOT_USER} -d ${DB_POSTGRES_DB}']
interval: 5s
timeout: 5s
retries: 10
# Project URL: https://github.com/pgadmin-org/pgadmin4
# Docs URL: https://www.pgadmin.org/docs/pgadmin4/8.14/index.html
pgadmin:
image: dpage/pgadmin4:9.0.0
#image: dpage/pgadmin4:8.14.0
container_name: "pgadmin"
restart: always
networks: ['demo']
environment:
# *** Settings ***
- PGADMIN_LISTEN_PORT=80
# *** Users ***
- PGADMIN_DEFAULT_EMAIL=admin@acme.com
- PGADMIN_DEFAULT_PASSWORD=admin
depends_on:
- postgres
ports:
- 5050:80
volumes:
# *** Volume configuration ***
- ./pgadmin-data:/var/lib/pgadmin
# Project URL: https://github.com/n8n-io/n8n
# Docs URL: https://docs.n8n.io/
n8n:
image: n8nio/n8n:1.82.1
container_name: "n8n"
#container_name: "${PROJECT_NAME}n8n"
restart: always
networks: ['demo']
environment:
# *** General ***
- GENERIC_TIMEZONE=Europe/Madrid
- TZ=Europe/Madrid
- NODE_ENV=production
# *** Settings ***
- N8N_SECURE_COOKIE=false
- N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
- N8N_RUNNERS_ENABLED=true
# *** Database ***
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=${DB_POSTGRES_DB}
- DB_POSTGRESDB_USER=${DB_POSTGRES_NON_ROOT_USER}
- DB_POSTGRESDB_PASSWORD=${DB_POSTGRES_NON_ROOT_PASSWORD}
ports:
- 5678:5678
links:
- postgres
volumes:
# *** General configuration ***
- /var/run/docker.sock:/var/run/docker.sock:ro # Access to Docker on host machine
# *** Volume configuration ***
- ./database01-n8n-data/n8n:/home/node/.n8n
- ./database01-n8n-data/other:/home/node/
depends_on:
postgres:
condition: service_healthy
volumes:
db-data:
pgadmin-data:
database01-n8n-data:
networks:
demo:
name: demo
driver: bridge
Para ver como lanzarlo, ver fichero README dentro del de la sección "database".
Este ejemplo se puede lanzar individualmente desde Docker Compose o bien se ha montado una herramienta de gestión rápida sobre tecnología Makefile que ayudará en la gestión de la plataforma formativa de n8n.
- Esta aplicación se explicará en el README principal del repositorio
Prácticamente todo se mantiene igual a lo indicado en el punto 3.2.1. en combinación/integración con ejemplo de n8n utilizado el artículo "Acelerando los desarrollos con contenedores : n8n" . A excepción de que se han añadido una serie de variables de entorno relacionadas conexión a base de datos desde la herramienta n8n.
Nota: Estas variables de entorno de base de datos vienen dadas por el fichero .env
Paso 3: Verificación de la herramienta PostgreSQL
Verificaremos que podemos acceder a la base de datos desde pgadmin
Pasos a seguir:
- Verificar que se encuentran disponibles los 3 contenedores
- pgadmin
- postgres
- n8n
- REPETIR todos los pasos igual que antes hasta el momento de configurar el host del servidor donde se utilizará
- Nombre del servidor: n8n
- Hostname:: postgres
- El usuario n8n y su password
- Base de datos por: n8ndb

- Verificar que se ha creado servidor

Se podrá ver que se tiene acceso a este esquema propio de n8n
- Verificar la creación de todo el modelo de tablas, etc,

Paso 4: Verificación de la herramienta n8n
Verificar que podemos acceder a la herramienta
Pasos a seguir:
- Acceder a la plataforma de n8n: http://localhost:5678
- Seguir los pasos del primer arranque
- Crear un workflow "dummy" (no hace falta que funcione)

- Guardar el workflow con un nombre

- Parar los servicios desde Docker Compose
- Volver a arrancarlos
- Verificar que se ha persistido desde la interfaz de n8n
- Debería de aparecer el mismo workflow creado
Si queremos terminar de confirmar que todo está correcto podemos hacer dos comprobaciones más:
- Que en el directorio de configuración de n8n que se ha creado como un volumen local NO existe el fichero de configuración de SqlLite : database.sqlite
- Que se ha creado el workflow en la tabla asociada dentro de la herramienta. Para ello acceder al pgadmin, acceder a la tabla "workflow_entity"

4. Conclusiones
Tras las explicaciones de este artículo hemos podido ver como n8n hace uso de dos bases de datos con un enfoque muy diferentes. Por lo que su elección va a jugar un papel muy importante en las automatizaciones que se vayan a realizar en función del rendimiento, la estabilidad, confiabilidad y la escalabilidad.
Por un lado, hemos visto SQLite que te viene por defecto y permite hacer uso de la herramienta sin meterte en muchos líos de integraciones y demás. Por lo que, para algo rápido, pruebas de concepto y cosas sin mucho lio puede ser la mejor elección. Para cosas más "serías" entonces se aconseja usar PostgreSQL
También hemos practicado sobre la integración de PostgreSQL y n8n, al final hemos podido comprobar que se mantiene la persistencia, que era el objetivo principal que buscábamos.
Perdonar que en algunos momentos haya sido muy técnico, pero así hemos entrado en detalles de configuración de la herramienta y por lo tanto dominaremos un "poquito" más n8n.
Si al final necesitas una base de datos para n8n para dar cobertura a proyectos importantes entonces la elección es clara... PostgreSQL