Saltar al contenido

🚀 Guía Completa: Instalar N8N en HestiaCP con Docker y SSL Gratuito

hestia + docker + n8n

Este verano me ha tocado hacer un cambio de servidor, me sigo quedando con HestiaCP como mi panel principal, pero esta vez he decidido cambiar Debian 12 por Ubuntu 24.04 ya que está un poco más actualizado, reconfigurar mi Hestia para que solo trabaje con Nginx en vez de con Apache+Nginx y por último quería instalar una instancia de N8N en mi propio servidor para poder empezar a trabajarlo. N8N sobre Node.js y para simplificar un poco su configuración vamos a usar Docker para configurar N8N y después vamos a hacer una plantilla personalizada de Nginx para que trabaje con N8N.

Aquí tienes la guía ampliada con todos los comandos necesarios para una instalación exitosa:

Instalación y configuración del Docker Compose

Para empezar vamos a instalar Docker y Docker Compose.

Comandos para instalar Docker:

curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh
systemctl enable docker

Ahora vamos a crear una carpeta en /opt/n8n para alojar en ella la configuración de Docker.

sudo mkdir -p /opt/n8n
cd /opt/n8n

Una vez hecho esto vamos a crear los archivos .env para almacenar las variables y docker-compose.yml con la configuración de docker, vamos a configurar N8N para que guarde todo en PostgreSQL dentro del contenedor de Docker. Recuerda cambiar subdominio por tu subdominio si lo tienes configurado como tal y tudominio por el dominio donde va a apuntar en N8N_HOST, y configurar los datos de SMTP aunque esto lo puedes configurar en otro momento si lo ves necesario. Los datos de PostgreSQL puedes cambiarlos o dejarlos tal cual ya que esos datos van a correr dentro del contenedor de Docker.

sudo tee /opt/n8n/.env << 'EOF'
# Configuración N8N
N8N_PROTOCOL=https
N8N_HOST=subdominio.tudominio.com
N8N_PORT=5678
N8N_EDITOR_BASE_URL=https://${N8N_HOST}
WEBHOOK_URL=https://${N8N_HOST}/
N8N_RUNNERS_ENABLED=true
TRUST_PROXY=1
EXPRESS_TRUST_PROXY=true
N8N_PROXY_HOPS=1
N8N_SOCKET_IO_URL=wss://${N8N_HOST}
NODE_FUNCTION_ALLOW_EXTERNAL=axios,qs

# Base de datos
DB_TYPE=postgresdb
DB_POSTGRESDB_HOST=db
DB_POSTGRESDB_PORT=5432
DB_POSTGRESDB_DATABASE=n8n
DB_POSTGRESDB_USER=n8n
DB_POSTGRESDB_PASSWORD=n8n

# Variables extra
VUE_APP_URL_BASE_API=https://${N8N_HOST}
EXECUTIONS_DATA_PRUNE=true
EXECUTIONS_DATA_MAX_AGE=336
GENERIC_TIMEZONE=Europe/Madrid
N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true

# SMTP
N8N_EMAIL_MODE=smtp
N8N_SMTP_HOST=smtp.eu.mailgun.org
N8N_SMTP_PORT=465
N8N_SMTP_USER=user@domain.com
N8N_SMTP_PASS=lapassword
N8N_SMTP_SSL=true
N8N_SMTP_SENDER=user@domain.com

# PostgreSQL interno
POSTGRES_USER=n8n
POSTGRES_PASSWORD=n8n
POSTGRES_DB=n8n
EOF
sudo tee /opt/n8n/docker-compose.yml << 'EOF'
services:
  n8n:
    image: n8nio/n8n:latest
    container_name: n8n_app
    restart: always
    ports:
      - "${N8N_PORT}:${N8N_PORT}"
    environment:
      - N8N_PROTOCOL=${N8N_PROTOCOL}
      - N8N_HOST=${N8N_HOST}
      - N8N_PORT=${N8N_PORT}
      - N8N_EDITOR_BASE_URL=${N8N_EDITOR_BASE_URL}
      - WEBHOOK_URL=${WEBHOOK_URL}
      - N8N_RUNNERS_ENABLED=${N8N_RUNNERS_ENABLED}
      - TRUST_PROXY=${TRUST_PROXY}
      - EXPRESS_TRUST_PROXY=${EXPRESS_TRUST_PROXY}
      - N8N_PROXY_HOPS=${N8N_PROXY_HOPS}
      - N8N_SOCKET_IO_URL=${N8N_SOCKET_IO_URL}
      - DB_TYPE=${DB_TYPE}
      - DB_POSTGRESDB_HOST=${DB_POSTGRESDB_HOST}
      - DB_POSTGRESDB_PORT=${DB_POSTGRESDB_PORT}
      - DB_POSTGRESDB_DATABASE=${DB_POSTGRESDB_DATABASE}
      - DB_POSTGRESDB_USER=${DB_POSTGRESDB_USER}
      - DB_POSTGRESDB_PASSWORD=${DB_POSTGRESDB_PASSWORD}
      - NODE_FUNCTION_ALLOW_EXTERNAL=${NODE_FUNCTION_ALLOW_EXTERNAL}
      - VUE_APP_URL_BASE_API=${VUE_APP_URL_BASE_API}
      - EXECUTIONS_DATA_PRUNE=${EXECUTIONS_DATA_PRUNE}
      - EXECUTIONS_DATA_MAX_AGE=${EXECUTIONS_DATA_MAX_AGE}
      - GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
      - N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=${N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS}
      - N8N_EMAIL_MODE=${N8N_EMAIL_MODE}
      - N8N_SMTP_HOST=${N8N_SMTP_HOST}
      - N8N_SMTP_PORT=${N8N_SMTP_PORT}
      - N8N_SMTP_USER=${N8N_SMTP_USER}
      - N8N_SMTP_PASS=${N8N_SMTP_PASS}
      - N8N_SMTP_SSL=${N8N_SMTP_SSL}
      - N8N_SMTP_SENDER=${N8N_SMTP_SENDER}
    depends_on:
      - db

  db:
    image: postgres:17
    volumes:
      - db-data:/var/lib/postgresql/data
    environment:
      - POSTGRES_USER=${POSTGRES_USER}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_DB=${POSTGRES_DB}
    restart: unless-stopped

volumes:
  db-data:
EOF

Ahora ejecutamos el docker compose para levantar la aplicación, recuerda que tu carpeta actual tiene que ser /opt/n8n/ :

docker compose up -d

Esto levantará la aplicación, si quieres ver que todo va bien puedes consultar el log con el siguiente comando:

sudo docker logs n8n_app

Al principio te pondrá algo como Initializing n8n process n8n ready on ::, port 5678

Crear las plantillas para HestiaCP

Ahora vamos a crear las plantillas para HestiaCP, recuerda que para que funcione bien tienes que tener configurado HestiaCP solo con Nginx y sin Apache.

Crear plantilla HTTP para n8n:

sudo tee /usr/local/hestia/data/templates/web/nginx/php-fpm/n8n.tpl << 'EOF'
server {
listen %ip%:%web_port%;
server_name %domain_idn% %alias_idn%;
error_log /var/log/%web_system%/domains/%domain%.error.log error;

    location / {
        proxy_pass http://127.0.0.1:5678;
        proxy_http_version 1.1;
        
        # Mejoras de rendimiento
        proxy_buffering off;
        proxy_cache off;
        chunked_transfer_encoding off;
        
        # Headers esenciales
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host $host;
        
        # WebSocket support
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        
        # Timeouts extendidos para n8n
        proxy_connect_timeout 7d;
        proxy_send_timeout 7d;
        proxy_read_timeout 7d;
    }

    # Bloquear acceso a archivos ocultos
    location ~ /\.(?!well-known\/|file) {
        deny all;
        return 404;
    }

    location /error/ {
        alias %home%/%user%/web/%domain%/document_errors/;
    }

    include %home%/%user%/conf/web/%domain%/nginx.ssl.conf_*;
}
EOF

Crear plantilla HTTPS para n8n:

sudo tee /usr/local/hestia/data/templates/web/nginx/php-fpm/n8n.stpl << 'EOF'
server {
    listen %ip%:%web_ssl_port% ssl http2;
    server_name %domain_idn% %alias_idn%;
    error_log   /var/log/%web_system%/domains/%domain%.error.log error;

    ssl_certificate     %ssl_pem%;
    ssl_certificate_key %ssl_key%;
    ssl_stapling        on;
    ssl_stapling_verify on;

    # TLS 1.3 0-RTT anti-replay
    if ($anti_replay = 307) { return 307 https://$host$request_uri; }
    if ($anti_replay = 425) { return 425; }
    include %home%/%user%/conf/web/%domain%/nginx.hsts.conf*;

    location / {
        proxy_pass http://127.0.0.1:5678;
        proxy_http_version 1.1;
        
        # Mejoras de rendimiento
        proxy_buffering off;
        proxy_cache off;
        chunked_transfer_encoding off;
        
        # Headers esenciales
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host $host;
        
        # WebSocket support
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        
        # Timeouts extendidos para n8n
        proxy_connect_timeout 7d;
        proxy_send_timeout 7d;
        proxy_read_timeout 7d;
    }

    # Bloquear acceso a archivos ocultos
    location ~ /\.(?!well-known\/|file) {
        deny all;
        return 404;
    }

    location /error/ {
        alias %home%/%user%/web/%domain%/document_errors/;
    }

    include %home%/%user%/conf/web/%domain%/nginx.ssl.conf_*;
}
EOF

Cargar plantilla y cargar el certificado SSL

Por último creamos el dominio y/o subdominio donde vayamos a alojar el n8n y en opciones avanzadas en plantilla de NGINX cargamos la plantilla de N8N. A continuación podemos certificar el dominio/subdominio desde el propio panel de Hestia CP y si todo sale bien ya podrás acceder a N8N desde el navegador.

Este proceso a mí me ha costado mucho desarrollarlo ya que no había nada claro en internet de cómo hacerlo, espero que con este tutorial a ti te vaya mejor. Si tienes alguna pregunta o sugerencia me las puedes poner en los comentarios.

Compartir este Articulo