Ir al contenido
  1. Posts/

Nginx Proxy Manager vs Traefik: qué uso yo en el homelab y por qué

·1440 palabras·7 mins

Si llevas tiempo con el homelab, en algún momento llegaste al punto donde tienes cinco o seis servicios corriendo y necesitas acceder a todos por nombre de dominio en vez de por IP y puerto. Ahí es donde entra el reverse proxy.

Los dos más populares son Nginx Proxy Manager y Traefik. Los he usado los dos en producción, en momentos distintos de la vida de mi homelab, y tengo opiniones formadas sobre cuándo usar cada uno.

Qué hace un reverse proxy en el homelab
#

Antes de la comparativa, una explicación rápida por si esto es nuevo para ti.

En un homelab típico tienes varios servicios: Portainer en el puerto 9000, Jellyfin en el 8096, Nextcloud en el 8080, Home Assistant en el 8123. Para acceder a cada uno tienes que recordar la IP del servidor y el puerto. Incómodo y poco seguro si quieres exponer algo al exterior.

Un reverse proxy actúa como portero. Recibe todas las peticiones en los puertos 80 y 443, mira a qué dominio van dirigidas, y las redirige al servicio correcto. Así puedes tener jellyfin.mi-homelab.local y nextcloud.mi-homelab.local sin recordar puertos, y con certificado TLS en cada servicio.

También centraliza la gestión de certificados: en vez de configurar HTTPS en cada servicio por separado, lo haces una vez en el proxy.

Nginx Proxy Manager: la opción visual
#

NPM es básicamente Nginx con una interfaz web encima. Lo instalas como container Docker, abres la web, y añades tus proxies haciendo clic. Sin tocar un archivo de configuración si no quieres.

Lo bueno de NPM es que lo entiende cualquiera. Quieres que nextcloud.tu-dominio.com apunte a 192.168.1.10:8080? Rellenas tres campos y listo. Los certificados Let’s Encrypt se generan con un botón. La interfaz es simple pero cubre el 90% de los casos de uso.

Mi docker-compose para NPM es así de sencillo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
version: '3'
services:
  nginx-proxy-manager:
    image: jc21/nginx-proxy-manager:latest
    restart: unless-stopped
    ports:
      - '80:80'
      - '443:443'
      - '81:81'
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt

Puerto 80 y 443 para el tráfico, puerto 81 para la interfaz de administración. Todo guardado en volúmenes locales.

Después de levantar el contenedor, entras a http://tu-servidor:81, usas las credenciales por defecto, las cambias, y empiezas a añadir proxy hosts. En diez minutos tienes el primer servicio detrás del proxy con certificado válido.

Traefik: el proxy para cuando crecer es el plan
#

Traefik hace lo mismo pero de una manera completamente diferente. No tiene interfaz para configurar proxies manualmente. En cambio, detecta automáticamente los contenedores Docker que están corriendo y se configura solo basándose en labels.

Pones unas etiquetas en el docker-compose de cada servicio y Traefik lo detecta, genera el certificado, y empieza a enrutar el tráfico. Cuando el contenedor para, deja de enrutar. Cuando vuelve a arrancar, retoma. Todo automático.

Un ejemplo de cómo se ve la configuración en el servicio que quieres exponer:

1
2
3
4
5
6
7
8
services:
  whoami:
    image: traefik/whoami
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.rule=Host(`whoami.tu-dominio.com`)"
      - "traefik.http.routers.whoami.entrypoints=websecure"
      - "traefik.http.routers.whoami.tls.certresolver=letsencrypt"

Para Traefik en sí, necesitas un archivo de configuración estático (traefik.yml) y opcionalmente uno dinámico. Aquí un ejemplo básico:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
  websecure:
    address: ":443"

certificatesResolvers:
  letsencrypt:
    acme:
      email: [email protected]
      storage: /letsencrypt/acme.json
      tlsChallenge: {}

providers:
  docker:
    exposedByDefault: false
  file:
    directory: /etc/traefik/dynamic
    watch: true

La ventaja de este enfoque es que la configuración del proxy vive junto con la configuración del servicio. Si alguien más coge tu docker-compose de Nextcloud, puede ver exactamente cómo está expuesto. Todo está en el código, versionable en git.

Cuándo uso cada uno
#

He llegado a una conclusión bastante clara después de tener los dos en producción:

NPM es mejor para empezar y para setups más simples. Si tienes menos de diez servicios, no usas Kubernetes o Swarm, y prefieres una interfaz gráfica para gestionar todo, NPM te va a dar lo que necesitas sin fricción. También es mejor para esos servicios que no corren en Docker: si tienes algo en una VM o en un servidor físico, lo añades a NPM con IP y puerto y ya.

Traefik escala mejor cuando el homelab crece. Si usas Docker Compose para todo y tienes muchos servicios, el modelo de labels hace que añadir un nuevo servicio sea trivial. Además, Traefik tiene integración nativa con Kubernetes a través de sus CRDs (Custom Resource Definitions). Si algún día das el salto a K3s, Traefik encaja perfectamente como Ingress Controller.

En mi caso, empecé con NPM porque fue lo primero que encontré que funcionaba. Lo usé durante más de un año sin problemas. El momento en que lo reemplazé por Traefik fue cuando monté el cluster K3s: en ese contexto, NPM no tiene sentido porque Kubernetes tiene su propia forma de gestionar el tráfico entrante, y Traefik se integra de forma nativa como controlador de ingress.

Certificados y DNS challenge
#

Aquí hay un punto importante donde Traefik tiene ventaja.

Si quieres certificados wildcard (*.tu-dominio.com) para cubrir todos tus subdominios con un solo certificado, necesitas el DNS challenge de Let’s Encrypt. Traefik soporta DNS challenge con decenas de proveedores DNS (Cloudflare, OVH, Route53, etc.) de forma nativa y bien documentada.

NPM también soporta DNS challenge pero la configuración es menos intuitiva y hay menos documentación en español sobre cómo montarlo. He visto gente perder horas en esto.

Si tienes Cloudflare como DNS (que recomiendo para el homelab), con Traefik es así:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
certificatesResolvers:
  cloudflare:
    acme:
      email: [email protected]
      storage: /letsencrypt/acme.json
      dnsChallenge:
        provider: cloudflare
        resolvers:
          - "1.1.1.1:53"
          - "8.8.8.8:53"

Y las credenciales de Cloudflare las pasas como variables de entorno. En quince minutos tienes certificados wildcard funcionando.

Middlewares y seguridad
#

Traefik tiene un sistema de middlewares bastante potente. Con poco código puedes añadir autenticación básica, rate limiting, cabeceras de seguridad, o integración con servicios de autenticación externos como Authelia.

Un middleware de autenticación básica, por ejemplo:

1
2
3
labels:
  - "traefik.http.middlewares.basic-auth.basicauth.users=usuario:$$contraseña-hasheada"
  - "traefik.http.routers.mi-servicio.middlewares=basic-auth"

NPM también tiene algo de esto en su interfaz pero es más limitado. Para casos de uso avanzados, Traefik gana claramente.

Rendimiento
#

En teoría, Traefik tiene algo más de overhead que Nginx puro por su modelo dinámico. En la práctica, con el hardware de cualquier homelab moderno, no notarás diferencia. Ambos son más que suficientes para cientos de peticiones por segundo.

Lo que sí he notado es que Traefik usa algo más de memoria que NPM en idle. NPM con diez servicios configurados apenas toca los 50-60 MB. Traefik en un setup similar puede estar en 80-100 MB. Para un servidor con varios gigas de RAM, irrelevante.

El dashboard de Traefik
#

Una cosa que me gusta de Traefik es su dashboard. Muestra en tiempo real todos los routers, servicios y middlewares activos, con estado de health check incluido. Para diagnosticar por qué un servicio no está siendo enrutado correctamente, es muy útil.

Para habilitarlo, añade esto al traefik.yml:

1
2
3
api:
  dashboard: true
  insecure: false

Y expónlo detrás del propio Traefik con autenticación. No lo dejes insecure: true en producción.

Mi recomendación según el caso
#

Si estás montando tu primer reverse proxy y quieres algo funcionando esta tarde: NPM sin dudarlo. Bajo a la calle en diez minutos con el primer servicio expuesto.

Si ya tienes experiencia con Docker, usas docker-compose para todo, y te gusta que la infraestructura esté en código: Traefik. La curva de aprendizaje existe pero es corta y el resultado es más limpio.

Si tienes K3s o cualquier Kubernetes: Traefik como Ingress Controller. No hay equivalente de NPM que encaje ahí.

Y si tienes NPM montado y funciona bien: no lo cambies sin motivo. “Funciona bien” es suficiente justificación para no tocar nada.

Recursos para empezar
#

Para NPM, la documentación oficial en nginxproxymanager.com es más que suficiente para el 90% de los casos.

Para Traefik, el punto de partida es doc.traefik.io. Es extensa pero bien organizada. Lo que más me ayudó al principio fue buscar ejemplos de docker-compose completos en GitHub con Traefik ya configurado.

Si montas uno de los dos y te atascas en algo concreto, deja un comentario con el error y lo miramos. Los logs de Traefik en modo debug son bastante explícitos sobre qué está fallando, que es algo que se agradece.


En el próximo artículo sobre redes voy a hablar de cómo combino Traefik con Cloudflare Tunnels para exponer servicios sin abrir ningún puerto en el router. Si esto te interesa, suscríbete para no perdértelo.