← Todos los artículos

n8n autoalojado en Google Cloud gratis: e2-micro, Docker y Traefik

Tener tu propio n8n es la forma más barata de automatizar en serio: sin precio por ejecución, sin límite de workflows y con tus datos en tu servidor. El nivel Always Free de Google Cloud incluye una VM e2-micro cada mes, suficiente para tener n8n funcionando 24/7 — siempre que respetes su 1 GB de RAM.

Esta guía es el setup que uso en producción: Docker Compose, Traefik v3 para HTTPS automático con Let's Encrypt, y el ajuste de memoria que evita que el OOM killer del kernel congele la máquina.

Resumen — e2-micro en una región gratuita de EE. UU., disco estándar de 30 GB, 2 GB de swap, Traefik + n8n en Docker con un tope de 750 MB y limpieza agresiva de ejecuciones.


Qué vas a montar

Pieza Función
GCP Compute Engine e2-micro 2 vCPU compartidas, 1 GB de RAM, Ubuntu 24.04 LTS
Traefik v3 Proxy inverso, redirección HTTP→HTTPS, certificados TLS automáticos
n8n El motor de automatización, con memoria limitada y limpieza de ejecuciones
Swap (2 GB) Red de seguridad: los picos de memoria ralentizan en vez de tumbar

Requisitos

  1. Una cuenta de Google Cloud con facturación activada (obligatoria incluso para recursos gratuitos).
  2. Un dominio propio — apuntarás n8n.tudominio.com a la VM.
  3. Soltura básica con SSH y la terminal.

Paso 1 — Crear la VM (y que siga siendo gratis)

El nivel gratuito es estricto con el dónde y el qué. Si te equivocas en algo de esto, te cobrarán.

En Compute Engine → Instancias de VM → Crear instancia:

  • Nombre: n8n
  • Región: us-west1, us-central1 o us-east1 — solo estas tres califican.
  • Tipo de máquina: Uso general → E2 → e2-micro.
  • Disco de arranque: Ubuntu 24.04 LTS, disco persistente estándar, hasta 30 GB. El disco Balanceado que viene por defecto no es gratis — cámbialo.
  • Firewall: marca Permitir tráfico HTTP y Permitir tráfico HTTPS.
  • Redes → Dirección IPv4 externa: reserva una dirección estática para que el DNS no se rompa tras un reinicio.

Pulsa Crear y añade un registro A para n8n.tudominio.com apuntando a esa IP. Hazlo ya: la emisión del certificado en el paso 5 necesita que el DNS resuelva.

Control de costes: las reglas del nivel gratuito (y el precio de las IPv4 externas) cambian de vez en cuando. Crea una alerta de presupuesto en Facturación → Presupuestos y alertas de 1 €/1 $ para que cualquier sorpresa llegue a tu correo y no a tu factura.


Paso 2 — Añadir swap (el paso que todos se saltan)

Con 1 GB de RAM, Docker + Traefik + Node.js dejan muy poco margen. Basta un workflow que descargue un archivo grande para que el OOM killer empiece a matar procesos — y muchas veces la VM queda inaccesible hasta que la reinicias.

Un archivo de swap de 2 GB convierte esos picos en una breve ralentización. Entra por SSH (el botón SSH de la consola sirve) y ejecuta:

# Crear y proteger un archivo de swap de 2 GB
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

# Mantenerlo tras reiniciar
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

# Priorizar la RAM, usar swap solo bajo presión
echo 'vm.swappiness=20' | sudo tee /etc/sysctl.d/99-swappiness.conf
sudo sysctl --system

# Comprobar
free -h

Paso 3 — Instalar Docker

sudo apt update && sudo apt upgrade -y

# Script oficial: Docker Engine + plugin de Compose
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

# Usar docker sin sudo (aplica en nuevas sesiones)
sudo usermod -aG docker $USER
newgrp docker

docker --version && docker compose version

No necesitas ufw: el firewall de la VPC de GCP ya bloquea todo salvo SSH, HTTP y HTTPS. Activar ufw sin permitir antes el puerto 22 es la forma clásica de quedarte fuera.


Paso 4 — Configurar n8n y Traefik

mkdir -p ~/n8n-docker/local-files
cd ~/n8n-docker

El archivo .env

nano .env
DOMAIN_NAME=tudominio.com
SUBDOMAIN=n8n
SSL_EMAIL=tu@email.com
GENERIC_TIMEZONE=Europe/Madrid

# Cifra las credenciales que guarda n8n. Genérala una vez con:
#   openssl rand -hex 32
# y guarda una copia en un lugar seguro — sin ella, un backup restaurado no puede leer sus credenciales.
N8N_ENCRYPTION_KEY=pega-aqui-tu-clave

El docker-compose.yml

nano docker-compose.yml
services:
  traefik:
    # Traefik < 3.6.1 no puede hablar con Docker Engine 29+ (versión de API demasiado antigua).
    image: traefik:v3.6
    restart: always
    command:
      - "--api=false"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.web.http.redirections.entrypoint.to=websecure"
      - "--entrypoints.web.http.redirections.entrypoint.scheme=https"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.le.acme.tlschallenge=true"
      - "--certificatesresolvers.le.acme.email=${SSL_EMAIL}"
      - "--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - traefik_data:/letsencrypt
      - /var/run/docker.sock:/var/run/docker.sock:ro
    deploy:
      resources:
        limits:
          memory: 96M

  n8n:
    image: docker.n8n.io/n8nio/n8n:stable
    restart: always
    labels:
      - traefik.enable=true
      - traefik.http.routers.n8n.rule=Host(`${SUBDOMAIN}.${DOMAIN_NAME}`)
      - traefik.http.routers.n8n.entrypoints=websecure
      - traefik.http.routers.n8n.tls=true
      - traefik.http.routers.n8n.tls.certresolver=le
      - traefik.http.services.n8n.loadbalancer.server.port=5678
      - traefik.http.middlewares.n8n-headers.headers.contentTypeNosniff=true
      - traefik.http.middlewares.n8n-headers.headers.forceSTSHeader=true
      - traefik.http.middlewares.n8n-headers.headers.stsSeconds=31536000
      - traefik.http.middlewares.n8n-headers.headers.stsIncludeSubdomains=true
      - traefik.http.routers.n8n.middlewares=n8n-headers@docker
    environment:
      - N8N_HOST=${SUBDOMAIN}.${DOMAIN_NAME}
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - NODE_ENV=production
      - WEBHOOK_URL=https://${SUBDOMAIN}.${DOMAIN_NAME}/
      - GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
      - TZ=${GENERIC_TIMEZONE}
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}

      # Ajuste de memoria para una máquina de 1 GB
      - NODE_OPTIONS=--max-old-space-size=512
      - N8N_PAYLOAD_SIZE_MAX=16
      - EXECUTIONS_DATA_PRUNE=true
      - EXECUTIONS_DATA_MAX_AGE=48
      - EXECUTIONS_DATA_PRUNE_MAX_COUNT=2000
      - EXECUTIONS_DATA_SAVE_ON_SUCCESS=none
      - EXECUTIONS_DATA_SAVE_ON_ERROR=all
      - EXECUTIONS_DATA_SAVE_MANUAL_EXECUTIONS=true
    deploy:
      resources:
        limits:
          memory: 750M
    volumes:
      - n8n_data:/home/node/.n8n
      - ./local-files:/files

volumes:
  n8n_data:
  traefik_data:

Por qué estos ajustes

Traefik

  • Desafío TLS: Traefik solicita y renueva los certificados de Let's Encrypt por el puerto 443 él solo — sin certbot ni cron.
  • HTTP → HTTPS: todo lo que llega al puerto 80 se redirige.
  • Sin puerto de n8n expuesto: el 5678 solo es accesible dentro de la red de Docker; desde internet solo se habla con Traefik.
  • exposedbydefault=false: solo se publican los contenedores con traefik.enable=true.

n8n

  • --max-old-space-size=512 mantiene el heap de Node.js en un tamaño predecible, así el recolector de basura actúa antes de que el contenedor llegue a su límite.
  • La limpieza de ejecuciones (EXECUTIONS_DATA_*) evita que la base de datos SQLite se llene con los datos de las ejecuciones correctas. Las fallidas se guardan 48 horas para poder depurarlas.
  • memory: 750M es un tope duro: si n8n se descontrola, Docker reinicia n8n — no la VM entera — y el sistema y Traefik conservan su parte.
  • N8N_ENCRYPTION_KEY explícita hace que tus backups sean portables. Si n8n la genera solo, vive únicamente dentro del volumen.
  • La etiqueta :stable en lugar de latest evita descargar versiones previas. Fija una versión exacta (p. ej. n8nio/n8n:1.x.y) si quieres actualizaciones totalmente reproducibles.

Paso 5 — Arrancar

docker compose up -d
docker compose logs -f traefik   # mira cómo se emite el certificado, Ctrl+C para salir

Abre https://n8n.tudominio.com y crea la cuenta de administrador. Hazlo enseguida — hasta entonces, cualquiera que encuentre la URL puede reclamar la instancia.

Vigilancia

docker stats                # CPU / RAM en vivo por contenedor
docker compose logs -f n8n  # logs de n8n
free -h                     # uso de RAM y swap

Paso 6 — Copias de seguridad

Todo lo importante vive en el volumen n8n_data. Para la mayoría de setups personales basta con un tarball diario:

mkdir -p ~/backups
docker run --rm \
  -v n8n-docker_n8n_data:/data:ro \
  -v ~/backups:/backup \
  alpine tar czf /backup/n8n-$(date +%F).tgz -C /data .

Añádelo a crontab -e (por ejemplo 0 3 * * *) y saca los archivos de la VM de vez en cuando. Exporta también los workflows importantes como JSON (o sincronízalos con Git): es el backup más barato que existe.


Solución de problemas

  • No se emite el certificado / aviso del navegador: el DNS debe resolver a la VM antes de arrancar Traefik. Compruébalo con dig +short n8n.tudominio.com y luego docker compose restart traefik.
  • client version 1.24 is too old en los logs de Traefik: usas una imagen de Traefik anterior a 3.6.1 con Docker 29+. Usa traefik:v3.6 o superior.
  • 404 de Traefik: la regla Host(...) no coincide con el dominio que escribiste — revisa el .env.
  • La VM se congela: confirma que el swap está activo (swapon --show) y busca Killed process en sudo dmesg.
  • Los webhooks muestran URLs con localhost: falta WEBHOOK_URL o está mal.

Actualizar

cd ~/n8n-docker
docker compose pull && docker compose up -d
docker image prune -f

Haz un backup antes y lee las notas de versión de n8n antes de saltos de versión mayor.


Y listo: un n8n de nivel producción en un hardware que no cuesta nada. Si construyes algo con él, me encantaría verlo — escríbeme desde el formulario de contacto.