532 - Exprimiendo tu proxy inverso Traefik
Aquí encontrarás una configuración del #proxy inverso #traefik para #docker sencilla y plenamente funcional con plugins para que lo exprimas al máximo
Hace ya muchos años que vengo utilizando un proxy inverso para dar salida a todos los servicios que tengo autoalojados en mi VPS. Aunque de vez en cuando pruebo algún que otro proxy inverso alternativo a Traefik, normalmente siempre vuelvo a Traefik. La cuestión es que con el paso del tiempo, y a pesar de que se ha ido actualizando Traefik, yo he seguido manteniendo la misma versión de mi archivo docker-compose.yml
, y no he aprovechado, hasta las últimas consecuencias, todas las posibilidades que me ofrece este proxy especializado en Docker. Así, en este episodio del podcast te voy a hablar sobre como estoy exprimiendo mi proxy inverso Traefik.
Exprimiendo tu proxy inverso Traefik
Un poquito de trasfondo
Como te decía en la introducción, he estado probando diferentes alternativas a Traefik, y una de las que mas me ha gustado a sido la versión de Caddy, utilizando etiquetas. Y esto ha sido así, mas que nada por su tremenda simplicidad.
La cuestión es que durante este tiempo de continuas actualizaciones de Traefik, en muy pocas ocasiones he modificado mi docker-compose.yml
, siguiendo aquella máxima de que si algo funciona no lo toques. Aunque tenía claro, que en este caso no era lo mas acertado, porque probablemente no estaba aprovechando todas las características que me ofrecía este proxy.
La cuestión, es que he levantado un nuevo VPS para los tutoriales, y en este nuevo VPS, he decidio exprimir Traefik al máximo. No solo aprovechando los complementos, sino reduciendo la configuración a la mínima expresión. A continuación encontrarás como quedan los archivos de configuración.
La estructura
La estructura de archivos que estoy utilizando para la configuración de Traefik es la siguiente,
.
├── config
│ ├── acme.json
│ ├── dynamic.yml
│ ├── traefik.yml
│ └── users.txt
├── docker-compose.yml
└── .env
El docker-compose
Empiezo primero con el docker-compose.yml
version: "3.7"
services:
traefik:
image: traefik:v2.10
container_name: traefik
init: true
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
ports:
- 80:80
- 443:443
environment:
- TZ=Europe/Madrid
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./config/traefik.yml:/traefik.yml:ro
- ./config/dynamic.yml:/dynamic.yml:ro
- ./config/users.txt:/users.txt:ro
- ./config/acme.json:/acme.json
- logs:/var/log/traefik
labels:
- traefik.http.services.traefik.loadbalancer.server.port=80
- traefik.http.routers.traefik-secure.entrypoints=websecure
- traefik.http.routers.traefik-secure.rule=Host(`${FQDN}`)
- traefik.http.routers.traefik-secure.middlewares=myauth@file
- traefik.http.routers.traefik-secure.service=api@internal
volumes:
logs: {}
networks:
proxy:
external: true
Aquí lo único destacable, quizá son las etiquetas, labels
. Mediante estas etiquetas defines todo lo que se refiere al servicio, por ejemplo, el puerto, el punto de entrada, la dirección y algunos servicios auxiliares.
Por ejemplo, en este caso, indico que el puerto en el que se levanta Traefik es el 80
, que estoy utilizando websecure
, que mas adelante verás que se corresponde con el puerto https
. Por otro lado, para dirigir el tráfico, indico la rule
, que hay, que viene a decir que todo el tráfico que vaya a ese FQDN
vaya a parar a Traefik
. Además utilizo un middleware, que es myauth@file
, que es para autenticación.
El FQDN
lo encontrarás en el archivo .env
, y será algo similar a,
FQDN=traefik.tuservidor.es
El archivo de configuración de traefik
El archivo de configuración de Traefik, traefik.yml
, es el siguiente,
api:
dashboard: true
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
permanent: true
websecure:
address: ":443"
http:
tls:
certresolver: letsencrypt
# middlewares:
# - mygeoblock@file
# - torblock@file
serversTransport:
maxIdleConnsPerHost: 1
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: true
network: proxy
file:
filename: /dynamic.yml
log:
level: INFO
filePath: "/var/log/traefik/traefik.log"
accessLog:
filePath: "/var/log/traefik/access.log"
bufferingSize: 100
fields:
defaultMode: keep
names:
ClientUsername: keep
headers:
defaultMode: keep
names:
Content-Type: keep
X-Forwarded-For: keep
filters:
statusCodes:
- "300-302"
- "400-409"
retryAttempts: true
minDuration: "10ms"
certificatesResolvers:
letsencrypt:
acme:
email: tu@correo.es
storage: acme.json
httpChallenge:
entryPoint: web
#experimental:
# plugins:
# GeoBlock:
# moduleName: "github.com/PascalMinder/geoblock"
# version: "v0.2.5"
# torblock:
# moduleName: "github.com/jpxd/torblock"
# version: "v0.1.1"
Como ves aquí indico dos puntos de entrada entryPoints
,
web
que utiliza el puerto 80, y que además redirecciona hacia el otro punto de entrada.websecure
que por contra utiliza el puerto 443, que emplealetsencrypt
para los certificados.
Por otro lado, indico los providers
, que en este caso son dos,
docker
, que se corresponde con el socket de Docker, y que utiliza la redproxy
para la comunicación. Yo le llaméproxy
, como le podía haber llamadopatata
, pero, me parecía que era lo mas identificativo.file
. Este nos permite definir configuraciones dinámicas, de forma que en el caso de que las actualicemos se cargarán inmediatamente.
Además de esto tienes,
- la definición de
log
, que me permite posteriormente ver que es lo que pasa en Traefik y en todos los servicios gestionados - el resolutor de certificado con su definición. Aquí te tienes que fijar que he indicado mi correo electrónico, el archivo donde se guarda, que este está mapeado en el
docker-compose.yml
, y el punto de entrada, que esweb
. - la definición de los plugins. Aunque en este caso, tal y como ves la tengo comentada. Tu puedes utilizar lo que quieras, simplemente tienes que descomentar, y configurar.
La configuración dinámica
La configuración dinámica permite en tiempo de ejecución modificar todos los parámetros que ves en este archivo,
http:
middlewares:
myauth:
basicAuth:
usersfile: /users.txt
# torblock:
# plugin:
# torblock:
# enabled: true
# mygeoblock:
# plugin:
# GeoBlock:
# allowLocalRequests: true
# logLocalRequests: false
# logAllowedRequests: false
# logApiRequests: false
# api: "https://get.geojs.io/v1/ip/country/{ip}"
# apiTimeoutMs: 500
# cacheSize: 25
# forceMonthlyUpdate: true
# allowUnknownCountries: false
# unknownCountryApiResponse: "nil"
# countries:
# - ES
# - US
En este caso están definidos varios middleware
. En concreto, empezamos por el único que está habilitado y que utilizo, en el propio docker-compose.yml
de Traefik, que si recuerdas, tenía la siguiente línea,
- traefik.http.routers.traefik-secure.middlewares=myauth@file
Aquí es donde indico <nombre-de-middleware>@<provider>
que en este caso es myauth@file
, que es el segundo de los provider que he configurado.
Este primer middleware, es uno de los que vienen definidos por defecto BasicAuth
, y que se encarga de añadir autenticación básica al servicio. Este es uno de las mas de 20 middleware que puedes utilizar con Traefik.
A parte de esto, también encontrarás un par de middleware, que son complementos, que están comentados. En concreto se trata de dos middleware, uno para bloquear todas las llamadas que vengan desde la red Tor, y el segundo, para bloquear todas las llamadas que no vengan de España o USA. Lo de USA lo tuve que añadir los servidores de LetsEncrypt
Añadir un nuevo Docker
Si quisiera añadir un nuevo servicio Docker, realmente, solo tengo que poner dos etiquetas. Por ejemplo, si quisiera añadir el servicio de Jellyfin, tan solo tendría que añadir,
- traefik.http.services.jellyfin.loadbalancer.server.port=8096
- traefik.http.routers.jellyfin.rule=Host(`${FQDN}`)
- traefik.http.routers.jellyfin.entrypoints=websecure
Incluso puedes quitar la última de las etiquetas, y funcionará perfectamente.
Conclusión
Como ves, la configuración ha quedado tremendamente simplificada, y además tienes la opción y posibilidad de utilizar los plugins que se encuentran dentro del sitio de Traefik.
Si no has probado ningún proxy, te recomiendo que lo pruebes y le des una oportunidad, porque te aseguro que te va a fascinar lo sencillo que es de configurar y poner en marcha.
Por último tienes los archivos de configuración en GitHub
Espero que te haya gustado este nuevo episodio del podcast. Si puedes, te agradecería una valoración en iVoox y/o en Apple Podcast.
Hola! Gran artículo! Me surge una duda…
Si pones diferentes servicios como el de jellyfin, siempre usas el mismo FQDN?
De que manera pondrías diferentes FQDNs? En el .env?
Hola Camilo,
Añade en tu fichero .env las variables FQDN2, FQDN3, etc. y luego en la configuración de los «labels» de Traefik de cada servicio cambia:
– traefik.http.routers.jellyfin.rule=Host(`${FQDN2}`)
….
– traefik.http.routers.jellyfin.rule=Host(`${FQDN3}`)
….
buenas tardes Lorenzo, soy Eugenio, asiduo lector y usuario de varios de tus servicios bajo docker.
Me he decidido a escribirte para ver si puedes ayudarme con un problemilla que me ha surgido con traefik, seguro que tu no le das ni pensada y a bote pronto sabes como solucionarlo pero yo llevo 2 días dándole vueltas al tema.
Traefik ha dejado de gestionar los certificados después de casi dos años. ¿y no se que le puede pasar.
Utilizo este articulo para crearlo y nada no gestiona, por eso no te envío ningún archivo.
Gracias por tu pensada y saludos
Pues nada Lorenzo, el anterior mensaje.. que ni lo mires.
Fue escribirte y se me ilumino la bombilla…. el acme.json como root
disculpa y gracias