DevSEO

Cómo instalar n8n en un VPS de Oracle Cloud

5 min read

Tu instancia de n8n no es un juguete, es infraestructura crítica. Por eso, en este tutorial vamos más allá de la instalación básica: vamos a montar un entorno Production Ready utilizando PostgreSQL como base de datos (olvida SQLite para cargas serias) y configurando un sistema de backups automáticos.

Si todavía no tienes tu servidor, revisa este tutorial para conseguir un VPS Always Free en Oracle.

Al lío.

📋 Requisitos Previos

  1. Dominio: Gestionado en Cloudflare.
  2. VPS Oracle Cloud: Con Ubuntu instalado y acceso SSH.

⚠️ Aviso crítico de red: Antes de tocar la terminal, ve a tu panel de Oracle Cloud > Networking > Security Lists y añade Ingress Rules para abrir los puertos 80 (HTTP) y 443 (HTTPS) desde 0.0.0.0/0. Sin esto, el firewall de la nube bloqueará todo tu tráfico.

Paso 1: Configuración del Sistema y Firewall (iptables)

Las imágenes de Ubuntu en Oracle son paranoicas por defecto. Vamos a abrir los puertos web en iptables antes de la regla de rechazo.

Actualiza el sistema:

sudo apt update && sudo apt upgrade -y
sudo apt install curl git nano -y

Configura las excepciones del firewall:

# Insertamos reglas antes del REJECT final (posición 6)
sudo iptables -I INPUT 6 -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
sudo iptables -I INPUT 6 -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT

# Hacemos las reglas persistentes
sudo apt install iptables-persistent netfilter-persistent -y
sudo netfilter-persistent save

Paso 2: Instalación de Docker

Docker necesita reiniciar su servicio tras la instalación para inyectar sus propias cadenas en iptables correctamente. No te saltes el reinicio.

curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
newgrp docker
sudo systemctl restart docker

Paso 3: Preparación DNS en Cloudflare

Para que la validación SSL funcione a la primera:

  1. Crea un registro A apuntando a la IP de tu VPS.
  2. Proxy Status: ☁️ Gris (DNS Only).
  3. Desactiva HTTP/3 (QUIC) en Speed > Optimization para evitar errores de protocolo en Chrome.

Paso 4: Despliegue de n8n con PostgreSQL

Aquí es donde nos ponemos serios. Usaremos PostgreSQL 16 para asegurar rendimiento y estabilidad en flujos de trabajo complejos.

Crea el directorio y el archivo de composición:

mkdir ~/n8n && cd ~/n8n
nano docker-compose.yml

Pega esta configuración. IMPORTANTE: Cambia n8n.tu-dominio.com y establece contraseñas seguras donde se indica.

version: '3.8'

services:
  postgres:
    image: postgres:16
    restart: always
    environment:
      - POSTGRES_USER=n8n
      - POSTGRES_PASSWORD=CAMBIA_ESTA_PASSWORD_DB  # <--- ¡CAMBIA ESTO!
      - POSTGRES_DB=n8n
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U n8n"]
      interval: 5s
      timeout: 5s
      retries: 5

  n8n:
    image: n8nio/n8n:latest
    restart: always
    ports:
      # Escuchamos solo en local. NGINX hará de proxy.
      - "127.0.0.1:5678:5678"
    environment:
      - N8N_HOST=n8n.tu-dominio.com
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - WEBHOOK_URL=https://n8n.tu-dominio.com/
      - NODE_ENV=production
      # Configuración de Base de Datos PostgreSQL
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=CAMBIA_ESTA_PASSWORD_DB  # <--- ¡MISMA QUE ARRIBA!
    volumes:
      - n8n_data:/home/node/.n8n
    depends_on:
      postgres:
        condition: service_healthy

volumes:
  n8n_data:
  postgres_data:

Levanta la infraestructura:

docker compose up -d

Paso 5: Nginx como Proxy Inverso

NGINX gestionará la terminación SSL y los WebSockets.

sudo apt install nginx -y
sudo nano /etc/nginx/sites-available/n8n

Configuración del bloque de servidor:

server {
    listen 80;
    server_name n8n.tu-dominio.com;

    location / {
        proxy_pass http://127.0.0.1:5678;
        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;

        # Soporte vital para WebSockets de n8n
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_buffering off;
    }
}

Activa y reinicia:

sudo ln -s /etc/nginx/sites-available/n8n /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx

Paso 6: Certificado SSL

Tener HTTPS no es opcional.

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d n8n.tu-dominio.com

Elige la opción 2 (Redirect) cuando te pregunte.

Paso 7: Hardening en Cloudflare

Ahora que el certificado está instalado, blinda la conexión:

  1. DNS: Activa la nube Naranja (Proxied).
  2. SSL/TLS: Modo Full (Strict).
  3. Edge Certificates: Activa “Always Use HTTPS”.

Paso 8: Sistema de Backups Automáticos

Un servidor sin backups es una bomba de relojería. Vamos a configurar un script que guarde la base de datos y los archivos de configuración cada noche.

Crea el script:

sudo nano /usr/local/bin/backup-n8n.sh

Contenido del script:

#!/bin/bash

# Directorio de backups
BACKUP_DIR="/home/ubuntu/n8n-backups"
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR

echo "--- Iniciando backup: $DATE ---"

# 1. Dump de PostgreSQL
# Nota: Ajusta 'n8n-postgres-1' si tu contenedor se llama diferente (ej: n8n_postgres_1)
docker exec n8n-postgres-1 pg_dump -U n8n n8n | gzip > $BACKUP_DIR/n8n-db-$DATE.sql.gz

# 2. Backup de archivos .n8n
# Ajusta la ruta del volumen si es necesario
VOL_PATH="/var/lib/docker/volumes/n8n_n8n_data/_data"
if [ -d "$VOL_PATH" ]; then
    tar -czf $BACKUP_DIR/n8n-files-$DATE.tar.gz -C "$VOL_PATH" . 2>/dev/null
else
    echo "ERROR: Volumen no encontrado en $VOL_PATH"
fi

# 3. Rotación (Mantiene últimos 7 días)
find $BACKUP_DIR -type f -name "*.sql.gz" -mtime +7 -delete
find $BACKUP_DIR -type f -name "*.tar.gz" -mtime +7 -delete

echo "--- Backup finalizado ---"

Dale permisos y prográmalo en cron:

sudo chmod +x /usr/local/bin/backup-n8n.sh
sudo crontab -e

Añade esta línea para ejecutarlo diariamente a las 03:00 AM:

0 3 * * * /bin/bash /usr/local/bin/backup-n8n.sh >> /var/log/n8n-backup.log 2>&1

🆘 Plan de Contingencia: Cómo Restaurar

Si ocurre un desastre, así es como recuperas tu servidor:

  1. Tumba el servicio: docker compose down
  2. Restaura archivos: Descomprime tu último .tar.gz en la carpeta del volumen n8n_data.
  3. Restaura la BD:
    • Levanta solo Postgres: docker compose up -d postgres
    • Copia el backup al contenedor: docker cp backup.sql.gz n8n-postgres-1:/tmp/
    • Ejecuta el restore:
      docker exec -it n8n-postgres-1 bash -c "gunzip -c /tmp/backup.sql.gz | psql -U n8n n8n"
  4. Arranca todo: docker compose up -d

Ahora tienes una infraestructura profesional, escalable y segura. Empieza a crear.