Traefik, mi nuevo mejor amigo
Saca provecho de tu servidor enrutando las peticiones de distintos servicios a través de un proxy inverso
Hace tiempo que contraté un VPS baratito y sencillo a más no poder, con la intención de tener una VPN a la que acceder desde una red pública cuando no me quedara otra opción, con el fin de minimizar riesgos (ya sabéis, mi "paranoia" de la seguridad). Todo iba bien, hasta que mi proveedor decidió que el plan que tenía contratado estaba "obsoleto" y debía migrar a otro superior... Le estaba dando uso a mi VPN, por lo que decidí hacerlo y, entonces, me encontré con que disponía de una máquina que podía hacer más por prácticamente lo mismo. Pero... ¿cómo podía sacarle partido y a la vez aprender algo nuevo?
Tras darle muchas vueltas al tema, llegué a la conclusión de que sería genial tener alojado en el VPS el blog, además de poder alojar copias de seguridad, trasteos varios, etc. Estaba empezando a meterme en el mundo de los contenedores y Docker, y prácticamente veía todas mis posibilidades ahí agrupadas.
Ahora bien, para ello tendría que exponer un sinfín de puertos al exterior y aunque tenía mi fiel fail2ban
y mi firewall protegiendo el sistema, no me parecía lo más acertado... Y entonces descubrí Traefik.
Traefik es una especie de enrutador y proxy inverso que se encarga de redirigir las peticiones recibidas por un puerto a los servicios que tiene registrados, donde cada uno está escuchando en su respectivo puerto. Esto cobra más sentido si encima dichos servicios corren en contenedores Docker, los cuales tienen cada uno su IP y pueden compartir el mismo "puerto" (por decirlo de alguna manera). De esta forma, podía exponer cualquier servicio que necesitara abriendo únicamente un puerto al exterior en mi VPS. Pero, ¿cómo hacer eso?
Primer paso: Instalar traefik
Para todo esto, doy por sentado que tenemos Docker en nuestro sistema ya instalado y configurado para poder ejecutar contenedores, así como docker compose para lanzar los mismos de una manera más sencilla. Así pues, el primer paso para correr Traefik fue crear mi fichero docker-compose.yml
con el siguiente contenido:
Y diréis "vale, muy bien, ¿pero qué es todo eso?...". Y tendréis razón 😂. Pero paciencia... que lo vamos a desgranar poco a poco:
El campo image
nos define la imagen de Docker que vamos a usar, en este caso la de Traefik 2.1, que a fecha de este artículo es la última.
Mediante container_name
le damos un nombre al contenedor, y con restart: always
le indicamos que queremos que se reinicie siempre en caso de problema.
En la parte de command
tenemos listadas varias órdenes, cada una de las cuales hace lo siguiente:
log.level=DEBUG
: Está comentada, pero si la descomentamos podremos ver el log de Traefik en ese nivel de traza (útil cuando nos dé problemas y no sepamos por qué).api.dashboard=true
: Con esto activamos el dashboard de Traefik, donde veremos todo lo que registra y el estado en el que está.api.insecure=true
: Al menos por ahora, nuestro dashboard no va a tener autenticación alguna, por lo que lo marcamos como tal.providers.docker=true
: Le indicamos el provider que va a usar, en nuestro caso, Docker.entrypoints.https.address=:443
: Definimos un punto de entrada, que se llamaráhttps
y que estará escuchando en el puerto 443.entrypoints.lan.address=:888
: Definimos otro punto de entrada, llamadolan
y que escuchará en el puerto 888. Ya veremos para qué usamos 2 puntos de entrada.certificatesResolver.leresolver.acme.email
: Definimos un "resolvedor" de certificados para poder exponer nuestros servicios bajo HTTPS y que nos los firmará la autoridad Let's Encrypt. En dicho "resolvedor" especificamos nuestro correo electrónico (ha de ser un correo válido).certificatesResolver.leresolver.acme.storage=acme.json
: Le indicamos a Traefik que nos almacene la información del certificado en el ficheroacme.json
.certificatesResolver.leresolver.acme.tlschallenge=true
: Le indicamos a Traefik que el certificado se obtendrá a través detlschallenge
, esto es, hará una llamada a Let's Encrypt y éste comprobará nuestro dominio a través del puerto 443 (con lo que dicho puerto deberá estar abierto a Internet y accesible).
Tras exponer los comandos, definimos los puertos que queremos exponer a nuestro sistema, en nuestro caso los puertos 443 para atender las peticiones HTTPS y el 8008 para las HTTP. La idea es que este último puerto no esté accesible desde Internet, pues aunque podría redirigir las conexiones HTTP a HTTPS, prefiero caparlo directamente, y usar ese puerto para las que no precisen de HTTPS dentro de mi red local. El puerto 8080 es en el que Traefik expone su dashboard, por lo que de momento lo exponemos para poder acceder a él.
A continuación, en volumes
cargamos el localtime
y el docker.sock
para que Traefik tenga acceso tanto a la hora local de sistema como a los cambios que se produzcan en Docker, y así detectar cuándo nuevos contenedores se crean o destruyen y ver si tiene que hacer algo al respecto (o no).
Por último, definimos una red que llamaremos, para este caso, traefiknet
y le indicamos al servicio que la use, así como en networks
la declaramos y la marcamos como externa.
Para crear dicha red, bastará con ejecutar el comando:
docker network create traefiknet
A continuación, en el mismo directorio donde tenemos nuestro fichero docker-compose.yml
crearemos un fichero vacío acme.json
que será donde se almacenen los certificados. Dicho fichero ha de pertenecer al usuario root
y ha de ser accesible sólo por él, por lo que ejecutamos lo siguiente:
touch acme.json
sudo chown root:root acme.json
sudo chmod 600 acme.json
¡Con esto, ya tendremos nuestro Traefik levantado y listo para registrar lo que sea! Bastará con ejecutar la orden docker-compose up -d
y podremos acceder a http://localhost:8080
para ver nuestro dashboard listo para registrar todo.
En posteriores entradas iré detallando cómo hacer que Traefik nos enrute las peticiones a otros servicios y contenedores 😊.