# n8n con HTTPS automatico (Traefik + Let's Encrypt) - ejemplo de la documentacion oficial de n8n
# Fuente: https://docs.n8n.io/hosting/installation/server-setups/docker-compose/  (consultada el 2026-11-05)
# La doc lo llama compose.yaml; Docker Compose acepta tambien el nombre docker-compose.yml.
# Los comentarios son nuestros; los valores son los del ejemplo oficial. No lo hemos probado en un servidor propio.
# Uso: copia este archivo y env.example (renombrado a .env) en una carpeta, crea ./local-files y ejecuta: docker compose up -d

services:                      # lista de contenedores que arranca Compose
  traefik:                     # primer servicio: el proxy inverso que gestiona HTTPS
    image: "traefik"           # imagen oficial de Traefik, sin etiqueta de version (usa la ultima; valora fijar una version)
    restart: always            # se reinicia solo si falla o si reinicia el servidor
    command:                   # opciones de arranque de Traefik
      - "--api.insecure=true"  # activa la API/panel de Traefik sin autenticacion; la doc de Traefik desaconseja el panel en produccion. Aqui no se publica su puerto
      - "--providers.docker=true"                      # Traefik descubre servicios leyendo las etiquetas (labels) de Docker
      - "--providers.docker.exposedbydefault=false"    # solo expone los contenedores con traefik.enable=true
      - "--entrypoints.web.address=:80"                # punto de entrada HTTP en el puerto 80
      - "--entrypoints.web.http.redirections.entryPoint.to=websecure"   # redirige HTTP hacia el punto de entrada seguro
      - "--entrypoints.web.http.redirections.entrypoint.scheme=https"   # ...usando el esquema https
      - "--entrypoints.websecure.address=:443"         # punto de entrada HTTPS en el puerto 443
      - "--certificatesresolvers.mytlschallenge.acme.tlschallenge=true"          # crea un resolvedor de certificados "mytlschallenge" con el reto TLS de Let's Encrypt
      - "--certificatesresolvers.mytlschallenge.acme.email=${SSL_EMAIL}"         # correo para solicitar el certificado (viene del .env)
      - "--certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json"  # donde se guardan los certificados
    ports:
      - "80:80"                # publica el puerto 80 (necesario para redireccion y validacion)
      - "443:443"              # publica el puerto 443 (HTTPS)
    volumes:
      - traefik_data:/letsencrypt                         # volumen persistente para los certificados
      - /var/run/docker.sock:/var/run/docker.sock:ro      # permite a Traefik leer Docker, en solo lectura (:ro)

  n8n:                         # segundo servicio: n8n
    image: n8nio/n8n           # imagen oficial; sin etiqueta = ultima version estable segun la doc
    restart: always            # reinicio automatico
    ports:
      - "127.0.0.1:5678:5678"  # el puerto 5678 solo escucha en el propio servidor (no se expone a internet); Traefik hace de puerta
    labels:                    # etiquetas que Traefik lee para enrutar
      - traefik.enable=true                                                             # este contenedor SI se expone via Traefik
      - traefik.http.routers.n8n.rule=Host(`${SUBDOMAIN}.${DOMAIN_NAME}`)               # atiende el dominio n8n.tu-dominio (del .env)
      - traefik.http.routers.n8n.tls=true                                               # usa TLS
      - traefik.http.routers.n8n.entrypoints=web,websecure                              # escucha en los puertos 80 y 443
      - traefik.http.routers.n8n.tls.certresolver=mytlschallenge                        # certificados con el resolvedor definido arriba
      - traefik.http.middlewares.n8n.headers.SSLRedirect=true                           # cabeceras de seguridad (middleware): redireccion a HTTPS
      - traefik.http.middlewares.n8n.headers.STSSeconds=315360000                       # HSTS: el navegador recordara usar HTTPS (10 anos)
      - traefik.http.middlewares.n8n.headers.browserXSSFilter=true                      # activa el filtro XSS del navegador
      - traefik.http.middlewares.n8n.headers.contentTypeNosniff=true                    # evita que el navegador adivine el tipo de contenido
      - traefik.http.middlewares.n8n.headers.forceSTSHeader=true                        # envia siempre la cabecera HSTS
      - traefik.http.middlewares.n8n.headers.SSLHost=${DOMAIN_NAME}                     # host usado en redirecciones SSL
      - traefik.http.middlewares.n8n.headers.STSIncludeSubdomains=true                  # HSTS tambien en subdominios
      - traefik.http.middlewares.n8n.headers.STSPreload=true                            # marca HSTS para listas de precarga
      - traefik.http.routers.n8n.middlewares=n8n@docker                                 # aplica el middleware anterior a este router
    environment:               # variables de entorno de n8n
      - N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true         # exige permisos restrictivos en el archivo de ajustes (que contiene la clave de cifrado)
      - N8N_HOST=${SUBDOMAIN}.${DOMAIN_NAME}              # nombre de host donde corre n8n (por defecto localhost)
      - N8N_PORT=5678                                      # puerto HTTP interno de n8n (por defecto 5678)
      - N8N_PROTOCOL=https                                 # protocolo con el que se llega a n8n (por defecto http)
      - NODE_ENV=production                                # modo produccion de Node.js
      - N8N_WEBHOOK_URL=https://${SUBDOMAIN}.${DOMAIN_NAME}/   # URL publica de los webhooks. La doc dice que requiere n8n 2.30.0 o posterior; en versiones anteriores usa WEBHOOK_URL
      - GENERIC_TIMEZONE=${GENERIC_TIMEZONE}               # zona horaria para Cron y nodos de programacion (del .env)
      - TZ=${GENERIC_TIMEZONE}                             # zona horaria del contenedor
      - N8N_RESTRICT_FILE_ACCESS_TO=/files                 # limita el acceso a archivos de los nodos a la carpeta /files
    volumes:
      - n8n_data:/home/node/.n8n     # volumen persistente: aqui viven la base SQLite, la clave de cifrado y la config
      - ./local-files:/files         # carpeta local del servidor accesible desde n8n como /files

volumes:                       # declaracion de los volumenes con nombre
  n8n_data:                    # datos de n8n (INCLUYELO en tus copias de seguridad)
  traefik_data:                # certificados de Traefik
