// DevOps
Instalamos n8n en FastPanel con Docker Compose: Guía clara
Publicado el 22.09.2026
En esta guía instalamos n8n en un servidor con panel FastPanel mediante Docker Compose. El propio n8n funciona en contenedores junto con PostgreSQL, Redis y un worker separado, y FastPanel se encarga del dominio, el certificado y del proxy inverso. La configuración repite el ejemplo oficial de n8n withPostgresAndWorker del repositorio n8n-hosting — con ajustes para FastPanel. La instalación sin panel, detrás de HAProxy, está descrita en el artículo «Instalación de n8n en Docker con HAProxy».
Qué se necesita
- Servidor con FastPanel y Docker instalado con el plugin
docker compose. - Dominio o subdominio para n8n, por ejemplo
n8n.example.com, con un registro A apuntando al servidor. - Acceso por SSH.
Los workers y Redis son necesarios cuando hay muchos procesos y éstos son largos: el proceso principal de n8n acepta webhooks y muestra el editor, mientras que la ejecución se delega a los workers. Para una instalación pequeña basta con un único contenedor n8n con PostgreSQL. Cómo funciona el modo de cola se explica en el artículo «n8n: Parte 5 — Escalado».
Paso 1: Preparación del servidor
sudo mkdir -p /opt/n8n_stack
cd /opt/n8n_stackPaso 2: Archivos de configuración
Se necesitan tres archivos: docker-compose.yml, .env y init-data.sh.
2.1. .env
N8N_VERSION=2.40.5
N8N_DOMAIN=n8n.example.com
# administrador de PostgreSQL
POSTGRES_USER=postgres_admin
POSTGRES_PASSWORD=reemplazar-por-una-contraseña-larga
POSTGRES_DB=n8n
# usuario de base de datos separado para n8n
POSTGRES_NON_ROOT_USER=n8n_user
POSTGRES_NON_ROOT_PASSWORD=reemplazar-por-otra-contraseña
# openssl rand -hex 32 — para cada una de las dos claves
ENCRYPTION_KEY=reemplazar
RUNNERS_AUTH_TOKEN=reemplazarENCRYPTION_KEY cifra las credenciales (credentials) en la base de datos de n8n. Génere esta clave una vez y guárdela separada del servidor: sin ella una copia de seguridad de la base de datos es inútil. RUNNERS_AUTH_TOKEN es el secreto compartido entre n8n y los contenedores task runners que ejecutan el código del nodo Code.
2.2. docker-compose.yml
La línea version: al inicio del archivo no es necesaria: Docker Compose moderno la ignora.
volumes:
db_storage:
n8n_storage:
redis_storage:
x-shared: &shared
restart: always
image: docker.n8n.io/n8nio/n8n:${N8N_VERSION}
environment:
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=${POSTGRES_DB}
- DB_POSTGRESDB_USER=${POSTGRES_NON_ROOT_USER}
- DB_POSTGRESDB_PASSWORD=${POSTGRES_NON_ROOT_PASSWORD}
- EXECUTIONS_MODE=queue
- QUEUE_BULL_REDIS_HOST=redis
- QUEUE_HEALTH_CHECK_ACTIVE=true
- N8N_ENCRYPTION_KEY=${ENCRYPTION_KEY}
- N8N_RUNNERS_MODE=external
- N8N_RUNNERS_AUTH_TOKEN=${RUNNERS_AUTH_TOKEN}
- N8N_RUNNERS_BROKER_LISTEN_ADDRESS=0.0.0.0
- OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS=true
- N8N_HOST=${N8N_DOMAIN}
- N8N_PROTOCOL=https
- WEBHOOK_URL=https://${N8N_DOMAIN}/
- N8N_PROXY_HOPS=1
- GENERIC_TIMEZONE=Europe/Moscow
- TZ=Europe/Moscow
volumes:
- n8n_storage:/home/node/.n8n
depends_on:
redis:
condition: service_healthy
postgres:
condition: service_healthy
x-runner: &runner
restart: always
image: n8nio/runners:${N8N_VERSION}
services:
postgres:
image: postgres:18
restart: always
environment:
- POSTGRES_USER
- POSTGRES_PASSWORD
- POSTGRES_DB
- POSTGRES_NON_ROOT_USER
- POSTGRES_NON_ROOT_PASSWORD
- PGDATA=/var/lib/postgresql/data
volumes:
- db_storage:/var/lib/postgresql/data
- ./init-data.sh:/docker-entrypoint-initdb.d/init-data.sh
healthcheck:
test: ['CMD-SHELL', 'pg_isready -h localhost -U ${POSTGRES_USER} -d ${POSTGRES_DB}']
interval: 5s
timeout: 5s
retries: 10
redis:
image: redis:7-alpine
restart: always
volumes:
- redis_storage:/data
healthcheck:
test: ['CMD', 'redis-cli', 'ping']
interval: 5s
timeout: 5s
retries: 10
n8n:
<<: *shared
ports:
- "127.0.0.1:5678:5678" # FastPanel publica n8n al exterior
n8n-runner:
<<: *runner
environment:
- N8N_RUNNERS_AUTH_TOKEN=${RUNNERS_AUTH_TOKEN}
- N8N_RUNNERS_TASK_BROKER_URI=http://n8n:5679
depends_on:
- n8n
n8n-worker:
<<: *shared
command: worker
depends_on:
- n8n
n8n-worker-runner:
<<: *runner
environment:
- N8N_RUNNERS_AUTH_TOKEN=${RUNNERS_AUTH_TOKEN}
- N8N_RUNNERS_TASK_BROKER_URI=http://n8n-worker:5679
depends_on:
- n8n-workerQué ha cambiado respecto a instrucciones antiguas:
- Versiones. Imagen de n8n de la rama 2.x en lugar de 1.91, PostgreSQL 18 en lugar de 11 — el soporte para PostgreSQL 11 finalizó en 2023, y la 18 tendrá soporte hasta noviembre de 2030. La variable
PGDATAes necesaria para que Postgres 18 almacene los datos en el volumen montado. Si ya tienes una versión antigua en producción, no basta con cambiar la etiqueta: primero hazpg_dumpally después restaura en la nueva versión. - Modo de cola activado explícitamente:
EXECUTIONS_MODE=queueyQUEUE_BULL_REDIS_HOST=redis. Sin estas líneas el worker no recibe tareas y Redis queda inactivo. - Task runners. Desde n8n 2.0 el código del nodo Code se ejecuta en contenedores separados
n8nio/runners: el proceso principal y cada worker tienen su propio runner. - Ya no hay
healthcheck.jspropio: n8n tiene una comprobación integrada/healthz, y en el worker se activa con la variableQUEUE_HEALTH_CHECK_ACTIVE=true.
2.3. init-data.sh
El script se ejecuta una vez en el primer inicio de PostgreSQL y crea un usuario separado para n8n:
#!/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 "SETUP INFO: No Environment variables given!"
fichmod +x init-data.shLa línea GRANT CREATE ON SCHEMA public es obligatoria: desde PostgreSQL 15 un usuario normal no puede crear tablas en el esquema public sin el permiso explícito.
Paso 3: Arranque
cd /opt/n8n_stack
docker compose up -d
docker compose psTodos los servicios deberían pasar a estado running, y postgres y redis a healthy. Puedes comprobar n8n así:
curl -sf http://127.0.0.1:5678/healthz && echo OKPaso 4: Configuración en FastPanel
- En FastPanel abre Sitios → Agregar sitio y especifica el dominio que pusiste en
.env. - En la configuración del sitio activa el proxy inverso hacia
http://127.0.0.1:5678. - Emite un certificado Let’s Encrypt para el dominio y activa el redireccionamiento de HTTP a HTTPS.
- Añade soporte para WebSocket — el editor de n8n mantiene una conexión persistente con el servidor. Si el panel no lo añadió automáticamente, escribe estas directivas adicionales de nginx para ese proxy:
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;Más detalles sobre las capacidades del panel — en el artículo «Paneles de control de hosting: Parte 4 — FASTPANEL».
Paso 5: Primer acceso
Abre https://n8n.example.com. n8n te pedirá crear una cuenta de propietario — hazlo de inmediato, antes de que terceros encuentren la dirección. Ya no hay login y contraseña en variables de entorno: el soporte de basic auth se eliminó en n8n 1.0.
Después de iniciar sesión, comprueba el nodo Webhook: la URL del webhook debe empezar por https://n8n.example.com/.
Copias de seguridad y actualización
- Copiar: volcado de la base (
docker compose exec postgres pg_dump -U postgres_admin n8n > n8n.sql), el volumenn8n_storagey la clave de cifrado del archivo.env. - Actualizar: haz una copia, cambia
N8N_VERSIONen.enva la nueva versión y ejecutadocker compose pull && docker compose up -d. El proceso principal, los workers y los runners deben ejecutar la misma versión.
// Reviews
Reseñas relacionadas
Como siempre, rápido y de calidad. Para asuntos con los servidores, me dirijo a Mijaíl.
¡Como siempre, rápido y de calidad! Para asuntos relacionados con los servidores, me dirijo a Mijaíl.
// Contact
¿Necesitas ayuda?
Escríbeme y te ayudaré a resolver el problema
Respondo en un día laborable (03:00-13:00 GMT)
Или оставьте заявку здесь:
// Related