📝
Homelab

Traefik v3 como proxy inverso en Proxmox LXC: HTTPS para cada servicio autoalojado en 2026

Ricardo Gil
12 de octubre de 2026
7 min de lectura

Traducido del original en inglés. Read this article in English →

#Proxmox #Traefik #Self-Hosting #Reverse Proxy #LXC

Si corres más de tres servicios autoalojados, ya chocaste con el infierno de los puertos. Jellyfin en el 8096, Immich en el 2283, Forgejo en el 3000: recordar qué puerto corresponde a qué servicio deja de tener gracia muy rápido. Traefik v3 lo resuelve de forma limpia: un solo contenedor LXC maneja todo el tráfico de entrada, termina el TLS y enruta por hostname automáticamente. Sin bloques de nginx que editar a mano cada vez que agregas un servicio.

Este es un recorrido completo: crear el LXC, configurar Traefik v3 con los proveedores de Docker y de archivos, conectar Let's Encrypt con el desafío DNS-01 de Cloudflare y armar un stack de middlewares que vale la pena conservar. Al final, cada servicio tiene un subdominio HTTPS real con certificados que se renuevan solos, sin nada autofirmado.

¿Por qué Traefik y no Nginx Proxy Manager?

NPM está bien para empezar. Traefik es mejor para ingenieros. La diferencia clave: Traefik detecta contenedores Docker nuevos y reconfigura el enrutamiento automáticamente con etiquetas, sin clics en una interfaz ni ediciones manuales de configuración. Defines la ruta en tu docker-compose.yml y queda activa. El proveedor de archivos se encarga de los servicios que no son Docker (LXC simples, VMs, cualquier cosa con una IP). Traefik v3, lanzado en 2024, dejó atrás mucho lastre heredado y ajustó la API de middlewares.

La contrapartida es real: la sintaxis de configuración de Traefik tiene su curva de aprendizaje. Reserva entre 30 y 60 minutos la primera vez.

Hardware para este setup

Un mini PC Beelink EQ12 como host de Proxmox es suficiente: 16 GB de RAM, N100 y unos 6 W en reposo según el fabricante. Margen de sobra para un stack de homelab completo. Para almacenamiento, un SSD SATA Samsung 870 EVO de 1 TB para el sistema y un disco NAS WD Red Plus de 4 TB para el almacenamiento masivo. La red puede pasar por un switch administrable TP-Link TL-SG108E de 8 puertos con reservas DHCP fijas para cada nodo.

Si vas a crecer a algo más grande, el Minisforum MS-01 con doble 10GbE vale la inversión, y vas a querer un UPS CyberPower CP1500PFCLCD para mantener todo encendido durante cortes breves.

Paso 1: crea el LXC de Traefik

Usa el script de la comunidad: está mantenido y te ahorra 20 minutos:

bash
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/traefik.sh)"

Acepta los valores por defecto: Debian 12, 512 MB de RAM, 1 vCPU y 4 GB de disco. Asígnale una IP fija (en esta guía uso 192.168.0.10) y resérvala en el router. Después de crearlo, anota el ID del contenedor. Define el hostname:

bash
pct exec <CTID> -- hostnamectl set-hostname traefik

Paso 2: configuración estática (traefik.yaml)

La configuración estática vive en /etc/traefik/traefik.yaml dentro del LXC. Es la configuración de arranque de Traefik y no se recarga en caliente. Entra al LXC por SSH:

bash
pct enter <CTID>
nano /etc/traefik/traefik.yaml

Esta es una configuración estática lista para producción:

yaml
global:
  checkNewVersion: false
  sendAnonymousUsage: false

api:
  dashboard: true
  insecure: false

log:
  level: INFO
  filePath: /var/log/traefik/traefik.log

accessLog:
  filePath: /var/log/traefik/access.log

entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
  websecure:
    address: ":443"
    http:
      tls:
        certResolver: letsencrypt

certificatesResolvers:
  letsencrypt:
    acme:
      email: your@email.com
      storage: /etc/traefik/acme.json
      dnsChallenge:
        provider: cloudflare
        resolvers:
          - "1.1.1.1:53"
          - "8.8.8.8:53"

providers:
  file:
    directory: /etc/traefik/conf.d
    watch: true
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
    network: traefik_net

Decisiones clave: HTTP redirige automáticamente a HTTPS en el entrypoint, exposedByDefault: false significa que tú eliges qué contenedores exponer en lugar de exponer todo por accidente, y el desafío DNS-01 hace que no necesites el puerto 80 abierto hacia afuera, algo crítico en homelabs detrás de CGNAT.

Paso 3: token de API de Cloudflare para DNS-01

En Cloudflare: Profile → API Tokens → Create Token → plantilla "Edit zone DNS". Limítalo a tu zona específica. Copia el token.

Defínelo como variable de entorno en la unidad de systemd de Traefik:

bash
systemctl edit traefik

Agrega:

ini
[Service]
Environment="CF_DNS_API_TOKEN=your_cloudflare_token_here"

Crea el archivo de almacenamiento ACME y restringe sus permisos:

bash
touch /etc/traefik/acme.json
chmod 600 /etc/traefik/acme.json

Reinicia Traefik:

bash
systemctl restart traefik
journalctl -u traefik -f

La primera vez, prueba contra la CA de staging de Let's Encrypt agregando caServer: "https://acme-staging-v02.api.letsencrypt.org/directory" al bloque acme:. Hazlo antes de pasar a producción o vas a chocar con los límites de emisión.

Paso 4: proveedor de archivos, para servicios que no son Docker

El proveedor de archivos vigila /etc/traefik/conf.d/ y recarga en caliente cuando hay cambios. Crea un YAML por servicio o agrúpalos. Este es el del propio Proxmox en 192.168.0.100:8006:

yaml
# /etc/traefik/conf.d/proxmox.yaml
http:
  routers:
    proxmox:
      rule: "Host(`proxmox.yourdomain.com`)"
      service: proxmox
      tls:
        certResolver: letsencrypt
      middlewares:
        - secure-headers

  services:
    proxmox:
      loadBalancer:
        servers:
          - url: "https://192.168.0.100:8006"
        passHostHeader: true
        serversTransport: ignorecert

  serversTransports:
    ignorecert:
      insecureSkipVerify: true

  middlewares:
    secure-headers:
      headers:
        stsSeconds: 31536000
        stsIncludeSubdomains: true
        contentTypeNosniff: true
        frameDeny: true
        browserXssFilter: true

insecureSkipVerify es necesario por el certificado autofirmado de Proxmox; como Traefik termina el TLS hacia afuera, es seguro.

Paso 5: proveedor de Docker, enrutamiento automático de contenedores

Para servicios en Docker, usa etiquetas en tu docker-compose.yml. Este es el de Immich:

yaml
services:
  immich-server:
    image: ghcr.io/immich-app/immich-server:release
    networks:
      - traefik_net
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.immich.rule=Host(`photos.yourdomain.com`)"
      - "traefik.http.routers.immich.entrypoints=websecure"
      - "traefik.http.routers.immich.tls.certresolver=letsencrypt"
      - "traefik.http.services.immich.loadbalancer.server.port=2283"

networks:
  traefik_net:
    external: true

Primero crea la red compartida:

bash
docker network create traefik_net

Traefik ve la etiqueta, crea el router y el servicio y solicita un certificado, todo sin reiniciar. Por esto los ingenieros prefieren Traefik frente a las alternativas con interfaz gráfica.

Paso 6: protege el panel

No corras el panel con insecure: true. Agrega autenticación HTTP Basic:

bash
htpasswd -nb admin yourpassword

Pega la salida en una configuración del proveedor de archivos:

yaml
# /etc/traefik/conf.d/dashboard.yaml
http:
  routers:
    dashboard:
      rule: "Host(`traefik.yourdomain.com`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
      service: api@internal
      tls:
        certResolver: letsencrypt
      middlewares:
        - dashboard-auth

  middlewares:
    dashboard-auth:
      basicAuth:
        users:
          - "admin:$apr1$..."  # output from htpasswd

Firewall y redirección de puertos

Abre los puertos 80 y 443 en tu router apuntando a la IP fija del LXC de Traefik. Esa es la única exposición externa. Todo lo demás se queda interno. Si configuraste OPNsense como firewall de Proxmox, crea la regla NAT ahí en lugar de depender del router de tu proveedor: te da registro por regla y una segmentación por VLANs más fácil.

Si estás detrás de CGNAT o prefieres no redirigir ningún puerto, Traefik se combina perfectamente con Cloudflare Tunnel: Traefik maneja el enrutamiento interno y el TLS, y el túnel se encarga del acceso externo sin abrir el 443.

Problemas comunes

El certificado no se emite. El 99% de las veces son los permisos de acme.json o un token de Cloudflare con el alcance equivocado. Revisa journalctl -u traefik -f justo después de reiniciar: el mensaje de error es explícito.

502 Bad Gateway. Traefik llegó al router, pero el backend está caído o el puerto es incorrecto. Verifícalo con curl http://192.168.0.x:PORT desde dentro del LXC de Traefik.

El router no coincide. Las reglas distinguen mayúsculas y minúsculas. Host() requiere el hostname en minúsculas: Host('Photos.domain.com') no va a coincidir con una petición a photos.domain.com.

Seguridad del socket de Docker. Montar /var/run/docker.sock directamente le da a Traefik acceso equivalente a root sobre el demonio de Docker. En un entorno compartido o de confianza parcial, ponle delante docker-socket-proxy y limítalo a llamadas de API de solo lectura.

Cómo encaja en un stack más grande

Traefik es la capa de entrada: no reemplaza a un gestor de contenedores. Si usas Coolify v4 en Proxmox LXC, configura Coolify para usar Traefik como proxy en lugar del Caddy integrado. Los dos se llevan bien: Coolify maneja el ciclo de vida de los despliegues y Traefik se encarga del enrutamiento y los certificados.

Si quieres un nodo de Traefik dedicado y siempre encendido, separado de tu host principal de Proxmox, una Raspberry Pi 5 de 8 GB consume menos de 5 W en reposo. Combínala con una carcasa USB para SSD y un SSD de 120 GB para tener mejor resistencia a la escritura que con una tarjeta SD.

Veredicto

Traefik v3 es el proxy inverso correcto para un homelab que ya dejó de ser un juguete. La curva de aprendizaje es real, pero acotada: una vez que funcionan la configuración estática y la primera ruta del proveedor de archivos, cada servicio nuevo se agrega en cinco minutos. El enrutamiento automático por etiquetas de Docker es realmente mejor que cualquier alternativa con interfaz gráfica, y el flujo de Let's Encrypt + DNS-01 de Cloudflare te da certificados reales incluso detrás de CGNAT.

El script de la comunidad te lleva de cero a funcionando en menos de 10 minutos. Esta guía cubre el 90% de la configuración que el script deja en tus manos.


Aviso: este artículo contiene enlaces de afiliado. Si compras a través de ellos, puedo ganar una pequeña comisión sin costo extra para ti.

¿Quieres algo así para tu negocio?

Instalo infraestructura privada y autoalojada en Proxmox: IA, automatización y herramientas internas en hardware que es tuyo, documentado y entregado. Ver el stack de IA privada →

¿No sabes qué necesitas? Agenda una llamada gratis.

📬Newsletter semanal

Recibe lo mejor de homelab e IA

Sin spam. Un correo por semana. Te das de baja cuando quieras.

Comparte este artículo