Traefik como Proxy Inverso en Docker: Guía Completa de Configuración
Configura Traefik como proxy inverso en Docker con certificados TLS automáticos de Let's Encrypt. Guía paso a paso que cubre v3.7, la seguridad del dashboard y el despliegue de apps.
Actualizado Publicado 26 min de lectura

Si estás ejecutando Docker en un VPS y necesitas un proxy inverso que gestione los certificados TLS automáticamente, Traefik es la mejor opción. Yo he estado usando Cloudflare Tunnels para la mayoría de mis configuraciones, pero Traefik te da control total. Sin dependencia de túneles de terceros, certificados automáticos de Let’s Encrypt e integración nativa con Docker. En esta guía configuraremos Traefik como proxy inverso en Docker desde cero: creación del VPS, instalación de Docker, configuración de Traefik v3.7, seguridad del dashboard y tu primera app detrás del proxy.
Advertencia de Seguridad
La versión original de esta guía usaba Traefik v3.1, que llegó al fin de su vida útil el 28 de octubre de 2024 y tiene vulnerabilidades críticas conocidas (CVE-2024-45410, CVSS 7.5 HIGH según el NVD / 9.8 según el aviso de GitHub). Esta guía se ha actualizado a Traefik v3.7. Si estás ejecutando v3.1, actualiza inmediatamente.
Si necesitas un certificado wildcard de Let’s Encrypt con el reto DNS de Cloudflare, consulta: Certificado Wildcard GRATIS de Let’s Encrypt para Traefik con el Proveedor Cloudflare
¿Qué es Traefik?
Traefik es un proxy inverso y balanceador de carga moderno diseñado para entornos en contenedores. Dirige el tráfico hacia tus microservicios y aplicaciones descubriendo y configurando rutas automáticamente según tu infraestructura.
La integración de Traefik con Docker es lo que lo diferencia. Detecta nuevos contenedores y actualiza su configuración de enrutamiento automáticamente. No tienes que tocar un archivo de configuración cada vez que añades un servicio.
Características principales:
- Descubrimiento y configuración automática de servicios
- Soporte para múltiples protocolos (HTTP, HTTPS, TCP, UDP)
- Panel de monitorización integrado
- Integración con Let’s Encrypt para la gestión automática de certificados SSL/TLS
- Soporte para varios algoritmos de balanceo de carga
- Middleware para añadir funcionalidades extra como autenticación o limitación de tasa

La arquitectura de Traefik
La arquitectura de Traefik se basa en tres componentes principales: EntryPoints, Routers y Middlewares.
EntryPoints
Los EntryPoints son los puntos de entrada de red a Traefik. Definen los puertos y protocolos en los que Traefik escucha el tráfico entrante.
Qué hacen los EntryPoints:
- Definen los puertos de escucha para tráfico HTTP, HTTPS o UDP
- Se pueden configurar para los protocolos TCP y UDP
- Soportan múltiples EntryPoints (p. ej., uno para HTTP y otro para HTTPS)
- Se pueden asociar a direcciones IP específicas
Routers
Los Routers se encargan de conectar las peticiones entrantes con los servicios que pueden gestionarlas. Analizan las peticiones mediante reglas y las enrutan en consecuencia.
Qué hacen los Routers:
- Usan reglas para determinar qué peticiones deben gestionar
- Se pueden asociar a EntryPoints específicos
- Soportan ajustes de prioridad para gestionar reglas superpuestas
- Se pueden configurar para tráfico HTTP, TCP o UDP
Middlewares
Los Middlewares modifican las peticiones antes de que se envíen a tu servicio (o las respuestas antes de que se devuelvan a los clientes). Se pueden adjuntar a los routers y ofrecen una forma de aplicar modificaciones a peticiones o respuestas.
Qué hacen los Middlewares:
- Pueden modificar peticiones y respuestas
- Son encadenables (se pueden aplicar varios middlewares en secuencia)
- Ofrecen funcionalidades como autenticación, limitación de tasa, manipulación de cabeceras, etc.
- Se pueden reutilizar en varios routers
Traefik tiene tres componentes básicos: EntryPoints (dónde escucha), Routers (cómo gestiona las peticiones) y Middlewares (modificaciones de peticiones/respuestas). Juntos forman un sistema de enrutamiento flexible para entornos en contenedores.
Cómo configurar Traefik como proxy inverso para tus apps Docker
¿Quieres monitorizar los recursos del servidor como CPU, memoria y espacio en disco? Consulta: Cómo Monitorizar los Recursos del Servidor y de Docker
Después de ver qué es Traefik, vamos a repasar todos los pasos necesarios: crear y configurar un VPS, instalar Docker, configurar el DNS, poner en marcha Traefik con el dashboard y desplegar algunas aplicaciones.
1. Crear un servidor VPS
Necesitas un VPS con los puertos 22, 80 y 443 abiertos. Yo uso Hetzner o Hostinger para la mayoría de las configuraciones. Usa el firewall en la nube de tu proveedor si está disponible (p. ej., Hetzner Cloud Firewall). Es más fiable que UFW por sí solo por cómo interactúa Docker con iptables (más sobre esto en el Paso 4).
Los precios de los VPS subieron en general en 2026 — si estás replanteándote alquilar un servidor, mira qué cambió y cuándo gana un mini PC.
Para reforzar tu VPS más allá de las reglas básicas de firewall, considera asegurar tu VPS con CrowdSec. Funciona bien junto a Traefik.
2. Añadir SWAP
La mayoría de los VPS no tienen swap por defecto. Añádelo con:
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab3. Instalar Docker
El siguiente paso es instalar Docker y Docker Compose v2. Los comandos de abajo detectan automáticamente el nombre clave de tu distribución (funciona tanto para Ubuntu como para Debian):
# Add Docker's official GPG key
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository (auto-detects Ubuntu/Debian codename)
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginVerifica que la instalación funcionó:
docker --version
docker compose versionDeberías ver la salida de versión en ambos. Si docker compose version da error, el plugin de Compose no se instaló correctamente.
4. Configurar el firewall y actualizar el SO
Actualiza primero el SO:
sudo apt update && sudo apt upgrade -ySi estás usando UFW, abre los puertos necesarios:
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw --force enable
sudo ufw statusDocker se salta UFW
Docker manipula iptables directamente, lo que puede saltarse las reglas de UFW. Los contenedores con puertos publicados pueden ser accesibles aunque UFW bloquee ese puerto. Considera usar el firewall de tu proveedor de nube (p. ej., Hetzner Cloud Firewall) o la cadena DOCKER-USER de iptables. Consulta: Docker se salta las reglas del firewall UFW
Reinicia después de las actualizaciones:
reboot5. Crear la red Docker
Crea la red externa que Traefik y tus apps compartirán:
docker network create traefik-netVerifica:
docker network ls | grep traefik-netDeberías ver traefik-net en la lista con el driver bridge.
6. Crear el archivo Docker Compose del proxy inverso Traefik
Crea el directorio y navega hasta él:
mkdir -p /opt/stacks/traefik && cd /opt/stacks/traefikEsta guía usa el reto TLS-ALPN-01, que requiere que el puerto 443 sea accesible desde internet. Si necesitas certificados wildcard o no puedes abrir el puerto 443, usa el reto DNS en su lugar. Consulta: Certificado Wildcard de Let’s Encrypt para Traefik
La configuración recomendada usa un proxy de socket Docker para limitar el acceso de Traefik a la API de Docker. Si prefieres la versión más simple con el socket directo, usa la segunda pestaña de abajo.
Recomendado: Socket Proxy
Crea un archivo compose.yml:
services:
socket-proxy:
image: tecnativa/docker-socket-proxy:latest
container_name: socket-proxy
restart: unless-stopped
networks:
- traefik-net
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
CONTAINERS: 1
SERVICES: 1
TASKS: 1
NETWORKS: 1
security_opt:
- no-new-privileges:true
traefik:
image: traefik:v3.7
container_name: traefik
restart: unless-stopped
command:
#- --log.level=DEBUG
- --api.dashboard=true
- --ping=true
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --providers.docker.endpoint=tcp://socket-proxy:2375
- --providers.docker.network=traefik-net
- --entrypoints.http.address=:80
- --entrypoints.http.http.redirections.entrypoint.to=https
- --entrypoints.http.http.redirections.entrypoint.scheme=https
- --entrypoints.https.address=:443
- --certificatesresolvers.letsencrypt.acme.tlschallenge=true
#- --certificatesresolvers.letsencrypt.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
- [email protected]
- --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json
security_opt:
- no-new-privileges:true
networks:
- traefik-net
ports:
- 80:80
- 443:443
healthcheck:
test: ["CMD", "traefik", "healthcheck", "--ping"]
interval: 30s
timeout: 5s
retries: 3
env_file: .env
volumes:
- ./letsencrypt:/letsencrypt
labels:
- traefik.enable=true
- traefik.http.routers.traefik-secure.rule=Host(`traefik.yourdomain.com`)
- traefik.http.routers.traefik-secure.entrypoints=https
- traefik.http.routers.traefik-secure.service=api@internal
- traefik.http.routers.traefik-secure.tls.certresolver=letsencrypt
- traefik.http.routers.traefik-secure.middlewares=traefik-auth
- traefik.http.middlewares.traefik-auth.basicauth.users=${TRAEFIK_DASHBOARD_CREDENTIALS}
- traefik.http.routers.traefik-secure.tls=true
networks:
traefik-net:
external: trueSimple: Socket Directo
Si prefieres la configuración más simple sin proxy de socket, crea un archivo compose.yml:
services:
traefik:
image: traefik:v3.7
container_name: traefik
restart: unless-stopped
command:
#- --log.level=DEBUG
- --api.dashboard=true
- --ping=true
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --providers.docker.network=traefik-net
- --entrypoints.http.address=:80
- --entrypoints.http.http.redirections.entrypoint.to=https
- --entrypoints.http.http.redirections.entrypoint.scheme=https
- --entrypoints.https.address=:443
- --certificatesresolvers.letsencrypt.acme.tlschallenge=true
#- --certificatesresolvers.letsencrypt.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
- [email protected]
- --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json
security_opt:
- no-new-privileges:true
networks:
- traefik-net
ports:
- 80:80
- 443:443
healthcheck:
test: ["CMD", "traefik", "healthcheck", "--ping"]
interval: 30s
timeout: 5s
retries: 3
env_file: .env
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./letsencrypt:/letsencrypt
labels:
- traefik.enable=true
- traefik.http.routers.traefik-secure.rule=Host(`traefik.yourdomain.com`)
- traefik.http.routers.traefik-secure.entrypoints=https
- traefik.http.routers.traefik-secure.service=api@internal
- traefik.http.routers.traefik-secure.tls.certresolver=letsencrypt
- traefik.http.routers.traefik-secure.middlewares=traefik-auth
- traefik.http.middlewares.traefik-auth.basicauth.users=${TRAEFIK_DASHBOARD_CREDENTIALS}
- traefik.http.routers.traefik-secure.tls=true
networks:
traefik-net:
external: trueEsto monta el socket de Docker de solo lectura directamente en el contenedor de Traefik. Funciona bien para configuraciones de un solo usuario, pero la versión con proxy de socket de arriba limita el radio de impacto si Traefik se ve comprometido.
Opciones de comandos explicadas:
--api.dashboard=true: Activa el dashboard web de Traefik.--providers.docker=true: Activa Docker como proveedor para el descubrimiento automático de servicios.--providers.docker.exposedbydefault=false: Evita que Traefik exponga automáticamente todos los contenedores. Debes activar cada uno explícitamente.--providers.docker.endpoint=tcp://socket-proxy:2375: Conecta con la API de Docker a través del proxy de socket en lugar del socket sin procesar. (Omitido en la versión de socket directo.)--providers.docker.network=traefik-net: Indica a Traefik qué red Docker usar para enrutar el tráfico a los contenedores.--entrypoints.http.address=:80: Entrypoint HTTP en el puerto 80.--entrypoints.http.http.redirections.entrypoint.to=https: Redirige todo el tráfico HTTP a HTTPS.--entrypoints.http.http.redirections.entrypoint.scheme=https: Garantiza que la redirección use el esquema HTTPS. Para profundizar en las redirecciones de HTTP a HTTPS, consulta Redirección HTTP a HTTPS en Traefik.--entrypoints.https.address=:443: Entrypoint HTTPS en el puerto 443.--certificatesresolvers.letsencrypt.acme.tlschallenge=true: Activa el reto TLS-ALPN-01 para la obtención de certificados de Let’s Encrypt.[email protected]: Tu email para el registro en Let’s Encrypt y las notificaciones de caducidad.--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json: Dónde almacenar los certificados. Este archivo necesita permisos específicos (cubierto en el Paso 9).--ping=true: Activa el endpoint de healthcheck que usa el healthcheck de Docker.
Etiquetas del dashboard explicadas:
traefik.enable=true: Activa Traefik para este contenedor.traefik.http.routers.traefik-secure.rule=Host(traefik.yourdomain.com): Enruta las peticiones de este hostname al dashboard.traefik.http.routers.traefik-secure.entrypoints=https: Usa el entrypoint HTTPS.traefik.http.routers.traefik-secure.service=api@internal: Enruta a la API interna del dashboard de Traefik.traefik.http.routers.traefik-secure.tls.certresolver=letsencrypt: Usa Let’s Encrypt para los certificados TLS.traefik.http.routers.traefik-secure.middlewares=traefik-auth: Aplica el middleware de autenticación.traefik.http.middlewares.traefik-auth.basicauth.users=${TRAEFIK_DASHBOARD_CREDENTIALS}: Configura Basic Auth. Las credenciales vienen del archivo.env. Más sobre Autenticación Básica en Traefik.traefik.http.routers.traefik-secure.tls=true: Activa TLS para este router.
Reemplaza traefik.yourdomain.com por tu dominio real.
7. Crear el archivo .env con las credenciales del dashboard de Traefik
Instala htpasswd:
sudo apt install apache2-utils -yGenera un hash bcrypt y escríbelo en .env con el nombre de la variable:
echo "TRAEFIK_DASHBOARD_CREDENTIALS=$(htpasswd -nbB admin 'YourPassword123' | sed 's/\$/$$/g')" | sudo tee -a .envLa opción -B usa bcrypt. El sed 's/\$/$$/g' duplica cada $: Docker Compose interpola $VAR dentro de los archivos .env, así que un hash con un solo $ quedaría destrozado (las letras después de $ se tragan como una variable indefinida) y la autenticación fallaría silenciosamente con un 401. Con $$ el contenedor recibe el hash correcto con un solo $.
Verifica que el .env contiene el hash duplicado:
cat .env
# TRAEFIK_DASHBOARD_CREDENTIALS=admin:$$2y$$05$$...hash...Reemplázalo por la salida real del comando htpasswd.
Para producción, considera usar secretos de Docker Compose en lugar de archivos .env para las credenciales sensibles.
8. Apuntar el dominio a la IP de tu servidor
Crea un registro A para tu dominio apuntando a la IP del servidor. Para los subdominios, puedes:
- Crear registros A individuales para cada subdominio (p. ej.,
traefik.yourdomain.com,flowise.yourdomain.com) - Crear un registro A wildcard (
*.yourdomain.com) apuntando al servidor
Los registros individuales son más explícitos y fáciles de depurar. Si no usas un wildcard, asegúrate de que el registro traefik.yourdomain.com está creado antes de continuar.
Verifica la propagación del DNS:
dig traefik.yourdomain.com +shortDebería devolver la IP de tu servidor. Si no devuelve nada, espera unos minutos más. El reto TLS requiere que el DNS resuelva correctamente.
9. Iniciar Traefik y verificar los certificados TLS de Let’s Encrypt
Antes de empezar, crea el archivo acme.json con los permisos correctos:
mkdir -p ./letsencrypt
touch ./letsencrypt/acme.json
chmod 600 ./letsencrypt/acme.jsonPermisos de acme.json
Si acme.json no tiene permisos 600, Traefik se negará a arrancar o no podrá almacenar los certificados. Este es el problema n.º 1 entre los principiantes. Verifícalo con ls -la ./letsencrypt/acme.json: la salida debería mostrar -rw-------.
Inicia Traefik:
docker compose up -dVerifica que funciona:
-
Comprueba el estado del contenedor:
docker ps: el contenedor de Traefik debería mostrar “healthy” (el healthcheck tarda ~30 segundos). -
Revisa los logs para la emisión del certificado:
docker logs traefikBusca una línea sobre el certificado obtenido. Sin errores sobre acme.json ni permisos.
- Prueba la redirección HTTP→HTTPS:
curl -I http://traefik.yourdomain.comEspera un 301 Moved Permanently redirigiendo a HTTPS.
- Prueba el certificado TLS:
curl -vI https://traefik.yourdomain.com 2>&1 | grep -i "issuer"Debería mostrar issuer: CN=R3, O=Let's Encrypt, C=US (o similar). Si ves un certificado autofirmado, el DNS aún no se ha propagado o el puerto 443 no es accesible.
- Accede al dashboard: abre
https://traefik.yourdomain.comen tu navegador. Deberías obtener un aviso de Basic Auth y luego ver el dashboard de Traefik.
Durante las pruebas, descomenta la línea del servidor CA de staging en tu archivo compose para no agotar los límites de tasa de Let’s Encrypt. Vuelve al servidor de producción cuando todo funcione. Para más comandos esenciales de depuración de Docker, consulta: comandos esenciales de Docker
Nota sobre los certificados de Let’s Encrypt: actualmente los certificados son válidos durante 90 días. Traefik los renueva automáticamente (empezando 30 días antes de su caducidad). Let’s Encrypt está transicionando a certificados de 45 días para febrero de 2028. La renovación automática de Traefik lo gestionará de forma transparente, pero acme.json debe seguir teniendo permisos de escritura y el contenedor debe permanecer en ejecución para que las renovaciones funcionen.
10. Desplegar tu primera app detrás del proxy inverso Traefik
Ahora que Traefik está en marcha, podemos añadir aplicaciones. Aquí tienes un ejemplo de FlowiseAI con una base de datos PostgreSQL. Anteriormente usé FlowiseAI con Docker Compose detrás de Cloudflare Tunnels. Ahora usamos etiquetas de Traefik en su lugar:
services:
flowise-db:
image: postgres:16-alpine
hostname: flowise-db
networks:
- traefik-net
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- ./flowise-db-data:/var/lib/postgresql/data
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 5s
timeout: 5s
retries: 5
flowise:
image: flowiseai/flowise:latest
container_name: flowiseai
hostname: flowise
healthcheck:
test: wget --no-verbose --tries=1 --spider http://localhost:${PORT}
volumes:
- ./flowiseai:/root/.flowise
environment:
DEBUG: false
PORT: ${PORT}
FLOWISE_USERNAME: ${FLOWISE_USERNAME}
FLOWISE_PASSWORD: ${FLOWISE_PASSWORD}
APIKEY_PATH: /root/.flowise
SECRETKEY_PATH: /root/.flowise
LOG_LEVEL: info
LOG_PATH: /root/.flowise/logs
DATABASE_TYPE: postgres
DATABASE_PORT: 5432
DATABASE_HOST: flowise-db
DATABASE_NAME: ${POSTGRES_DB}
DATABASE_USER: ${POSTGRES_USER}
DATABASE_PASSWORD: ${POSTGRES_PASSWORD}
restart: on-failure:5
networks:
- traefik-net
depends_on:
flowise-db:
condition: service_healthy
entrypoint: /bin/sh -c "sleep 3; flowise start"
labels:
- "traefik.enable=true"
- "traefik.http.routers.flowise.rule=Host(`flowise.domain.com`)"
- "traefik.http.routers.flowise.entrypoints=https"
- "traefik.http.routers.flowise.tls.certresolver=letsencrypt"
- "traefik.http.services.flowise.loadbalancer.server.port=${PORT}"
networks:
traefik-net:
external: trueLa etiqueta flowiseai/flowise:latest siempre descarga la imagen más reciente. Para mayor estabilidad, consulta las versiones de Flowise y fija una versión concreta en su lugar.
Algunas cosas a tener en cuenta sobre esta configuración:
Tanto flowise-db como flowise están en traefik-net. La BD y Flowise también pueden compartir una red interna separada para el tráfico de la base de datos. Ambos solo necesitan traefik-net para que Traefik enrute el tráfico externo.
Las etiquetas específicas de Traefik le indican que enrute el tráfico de flowise.domain.com a este contenedor en el entrypoint HTTPS, usando Let’s Encrypt para TLS.
No publicamos ningún puerto del host. Traefik enruta el tráfico internamente a través de la red Docker. La etiqueta loadbalancer.server.port le indica a Traefik en qué puerto escucha la app dentro del contenedor.
Reemplaza flowise.domain.com por tu dominio real.
Crea el archivo .env para Flowise:
PORT=3000
POSTGRES_USER='user'
POSTGRES_PASSWORD='pass'
POSTGRES_DB='flowise'
FLOWISE_USERNAME=bitdoze
FLOWISE_PASSWORD=bitdozeSi el subdominio no usa un wildcard, asegúrate primero de que el registro A de flowise.domain.com apunta a la IP de tu servidor. Luego:
source .env
docker compose up -dVerifica: docker logs flowiseai y abre https://flowise.domain.com en tu navegador.
Para más ideas de contenedores Docker que desplegar detrás de Traefik, echa un vistazo a Contenedores Docker para tu servidor casero.
11. Instalar Dockge para gestionar tus archivos Docker Compose
Dockge es un gestor ligero de Docker Compose con interfaz web. Escribí una guía de instalación detallada de Dockge, gestor de Docker Compose. Así es como ejecutarlo detrás de Traefik.
Crea un directorio:
mkdir /opt/dockge
cd /opt/dockgeCrea un archivo compose.yml:
services:
dockge:
image: louislam/dockge:1
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /opt/stacks:/opt/stacks
environment:
- DOCKGE_STACKS_DIR=/opt/stacks
networks:
- traefik-net
labels:
- "traefik.enable=true"
- "traefik.http.routers.dockge.rule=Host(`dockge.domain.com`)"
- "traefik.http.routers.dockge.entrypoints=https"
- "traefik.http.routers.dockge.tls.certresolver=letsencrypt"
- "traefik.http.services.dockge.loadbalancer.server.port=5001"
networks:
traefik-net:
external: trueLa etiqueta louislam/dockge:1 sigue la versión principal, que es la práctica correcta para la estabilidad. Dockge 1.5.0+ desactiva por defecto la terminal/consola integrada por seguridad. Si necesitas acceso a la terminal, añade DOCKGE_ENABLE_CONSOLE=true a la sección de entorno.
Si no usas un wildcard para los subdominios, asegúrate de que el registro A de dockge.domain.com apunta a la IP de tu servidor. Luego:
docker compose up -dVerifica: docker logs dockge y abre https://dockge.domain.com en tu navegador.
Para una comparativa más amplia de herramientas de gestión autoalojadas, consulta paneles de gestión de servidores autoalojados.
Solución de problemas comunes
Traefik no arranca / errores de acme.json
La causa más común son permisos incorrectos en acme.json. Traefik requiere permisos 600 en este archivo.
ls -la ./letsencrypt/acme.json
# Should show: -rw------- 1 root root ...Si los permisos son incorrectos:
chmod 600 ./letsencrypt/acme.json
docker compose restart traefikRevisa también docker logs traefik para otros errores (conflictos de puertos, problemas de red).
Sin certificado / aviso de certificado autofirmado
Esto significa que el reto TLS falló. Causas comunes:
- DNS no propagado: verifica con
dig traefik.yourdomain.com +short: debe devolver la IP de tu servidor. - Puerto 443 no accesible: el reto TLS-ALPN-01 requiere conexiones entrantes en el puerto 443. Revisa tu firewall y los grupos de seguridad de tu proveedor de nube.
- Proxy de Cloudflare activado: si usas Cloudflare con la nube naranja (proxy), el reto TLS puede fallar. Prueba con la nube gris (solo DNS) durante la configuración.
Usa el servidor de staging mientras depuras para evitar los límites de tasa. Descomenta la línea caserver en tu archivo compose.
Ya se emitieron demasiados certificados
Límites de tasa de Let’s Encrypt: 5 certificados duplicados por dominio por semana. Si has estado depurando, puede que hayas llegado a ese límite.
Solución: cambia al servidor de staging mientras pruebas:
- --certificatesresolvers.letsencrypt.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directoryLos certificados de staging muestran avisos en el navegador, pero te permiten verificar que la configuración funciona. Vuelve a producción cuando todo esté confirmado.
Traefik no detecta los contenedores Docker
Comprueba dos cosas:
- El contenedor está en la red
traefik-net:
docker network inspect traefik-netTu contenedor debería aparecer en la salida.
- El contenedor tiene la etiqueta
traefik.enable=true:
docker inspect your-container | grep -i traefik.enableEl dashboard muestra 401 / la autenticación no funciona
La causa más común es un hash con un solo $ en .env que Docker Compose destroza al interpolarlo. Regenéralo con el escape $$ del Paso 7:
echo "TRAEFIK_DASHBOARD_CREDENTIALS=$(htpasswd -nbB admin 'YourPassword123' | sed 's/\$/$$/g')" | sudo tee .envAsegúrate de que el .env está en el mismo directorio que el archivo compose y de que la directiva env_file: .env está presente. Verifica también que la etiqueta del middleware referencia traefik-auth correctamente.
Bucle de redirección HTTP
Si estás detrás de Cloudflare, la causa más común es el modo SSL/TLS configurado en “Flexible” en lugar de “Full” (o “Full (strict)”). El modo “Flexible” de Cloudflare conecta con tu origen por HTTP, Traefik redirige a HTTPS, Cloudflare vuelve a conectar por HTTP, creando un bucle infinito.
Solución: en el panel de Cloudflare, ve a SSL/TLS y configúralo en Full (o Full (strict) si tienes un certificado válido).
Usa el servidor de staging de Let’s Encrypt mientras pruebas para no agotar los límites de tasa. Descomenta la línea caserver en tu archivo compose y vuelve a producción cuando todo funcione.
Notas de hardening y producción
Una vez que la configuración básica funciona, esto es lo que hay que hacer para producción:
- Proxy de socket (ya incluido en la configuración recomendada). Limita el acceso de Traefik a la API de Docker a información de solo lectura de contenedores/redes/servicios
- Middleware de cabeceras de seguridad: añade HSTS, protección contra sniffing de content-type, filtro XSS
- Middleware de limitación de tasa: protege el dashboard y las apps contra abusos
- Copia de seguridad de
acme.json: perderlo significa reemitir todos los certificados (y toparte con los límites de tasa). Haz copias periódicas o usa un volumen Docker en almacenamiento persistente - Usa secretos de Docker para las credenciales en lugar de archivos
.enven producción - Mantén Traefik actualizado.
traefik:v3.7sigue las versiones de parche v3.7.x. Comprueba periódicamente si hay nuevas versiones menores
Middleware de cabeceras de seguridad: añade estas etiquetas a los contenedores de tus apps:
- traefik.http.middlewares.sec-headers.headers.sslredirect=true
- traefik.http.middlewares.sec-headers.headers.stsseconds=63072000
- traefik.http.middlewares.sec-headers.headers.stsincludeSubdomains=true
- traefik.http.middlewares.sec-headers.headers.stspreload=true
- traefik.http.middlewares.sec-headers.headers.contentTypeNosniff=true
- traefik.http.middlewares.sec-headers.headers.browserXssFilter=trueMiddleware de limitación de tasa: añádelo a tu router:
- traefik.http.middlewares.rate-limit.ratelimit.average=100
- traefik.http.middlewares.rate-limit.ratelimit.burst=50
- traefik.http.routers.traefik-secure.middlewares=traefik-auth,rate-limitExplora los plugins de la comunidad en plugins.traefik.io para integración con CrowdSec, filtrado geográfico y más. Para un hardening más amplio del VPS, consulta: asegura tu VPS con CrowdSec
Conclusiones
Configurar Traefik como proxy inverso Docker para tus apps autoalojadas es sencillo una vez que sigues los pasos. Hemos cubierto la creación del VPS, la instalación de Docker, Traefik v3.7 con certificados TLS automáticos de Let’s Encrypt, la seguridad del dashboard con autenticación bcrypt, un proxy de socket para reducir el radio de impacto y el despliegue de tu primera app con etiquetas de Traefik.
Las mejoras clave sobre una configuración básica: el proxy de socket limita la exposición de la API de Docker, acme.json con los permisos adecuados previene el fallo más común entre principiantes, los healthchecks detectan problemas pronto y la autenticación bcrypt con el escape $$ gestionado en el Paso 7 mantiene el dashboard protegido.
Una vez que Traefik está en marcha, añadir nuevos servicios es solo cuestión de añadir etiquetas a un contenedor Docker y ponerlo en traefik-net. Dockge facilita aún más la gestión de esos archivos compose desde una interfaz web.


