Explicación de los archivos
traefik.yml
Se trata de la configuración estática y base de Traefik.
Primero le decimos a Traefik que queremos la interfaz gráfica de la web estableciendo dashboard:true
Después definimos nuestros dos entrypoints web (http) y websecure (https). Para el endpoint https se configura el certResolver para tener los certificados automáticos de Let’s Encrypt. A continuación se carga el middleware adecuado para que todo el tráfico sea reenviado a https.
En la parte de providers se especifica que este archivo será pasado a un contenedor docker usando bind mount. También se indica a Traefik que encuentre nuestra configuración dinámica en configurations/dynamic.yml. Y por último está la configuración para resolver certificados SSL.
# traefik.yml
api:
dashboard: true
entryPoints:
web:
address: :80
http:
redirections:
entryPoint:
to: websecure
websecure:
address: :443
http:
middlewares:
- secureHeaders@file
tls:
certResolver: letsencrypt
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
file:
filename: /configurations/dynamic.yml
certificatesResolvers:
letsencrypt:
acme:
email: manu@tudominio.es
storage: acme.json
keyType: EC384
httpChallenge:
entryPoint: web
Nota: Configurar un correo electrónico en este archivo para la renovación de Let’s Encrypt. Podría arrojar un error cuando quiera ejecutar su contenedor docker.
dynamic.yml
Este archivo contiene los middlewares para asegurar que todo el tráfico es totalmente seguro y se ejecuta sobre TLS. También se establece aquí la autentificación básica para el panel de control de Traefik, ya que por defecto es accesible para todo el mundo.
El archivo es totalmente dinámico y puede ser editado sobre la marcha, sin reiniciar nuestro contenedor.
# dynamic.yml
http:
middlewares:
secureHeaders:
headers:
sslRedirect: true
forceSTSHeader: true
stsIncludeSubdomains: true
stsPreload: true
stsSeconds: 31536000
user-auth:
basicAuth:
users:
- "userdocker:$apr1$MTqfVdtTiE$65kzT5ERfFqwH9f3uipxA1"
tls:
options:
default:
cipherSuites:
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
minVersion: VersionTLS12
docker-compose.yml
Este es el archivo más importante, donde ocurre la magía. La belleza de Traefik es que una vez hecha la configuración inicial, el despliegue de nuevos contenedores es muy fácil. Funciona especificando labels para cada contenedor.
# docker-compose.yml
version: "3"
services:
traefik:
image: traefik:latest
container_name: traefik
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
ports:
- 80:80
- 443:443
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik-data/traefik.yml:/traefik.yml:ro
- ./traefik-data/acme.json:/acme.json
- ./traefik-data/configurations:/configurations
labels:
- "traefik.enable=true"
- "traefik.docker.network=proxy"
- "traefik.http.routers.traefik-secure.entrypoints=websecure"
- "traefik.http.routers.traefik-secure.rule=Host(`traefik.yourdomain.com`)"
- "traefik.http.routers.traefik-secure.service=api@internal"
- "traefik.http.routers.traefik-secure.middlewares=user-auth@file"
portainer:
image: portainer/portainer-ce:latest
container_name: portainer
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./portainer-data:/data
labels:
- "traefik.enable=true"
- "traefik.docker.network=proxy"
- "traefik.http.routers.portainer-secure.entrypoints=websecure"
- "traefik.http.routers.portainer-secure.rule=Host(`portainer.yourdomain.com`)"
- "traefik.http.routers.portainer-secure.service=portainer"
- "traefik.http.services.portainer.loadbalancer.server.port=9000"
networks:
proxy:
external: true
Para cada contenedor que Traefik deba manejar se añaden labels para que Traefik sepa a dónde debe dirigirlo. Así que mirado este archivo se puede comprobar rápidamente lo que está pasando en el contenedor traefik.
La primera etiqueta es la que le dice a Traefik que debe enrutar este contenedor porque especificamos enable=true. Esto es el resultado de la configuración en el archivo estático traefik.yml donde explícitamente se indica exposedByDefault: false por lo que se tiene que especificar así.
La segunda etiqueta indica que se debe utilizar el proxy de red, el cual se creará más adelante. Después de eso se le dice a Traefik que use el endpoint websecure (https). Luego se especifica el nombre del host con el dominio apropiado.
La penúltima etiqueta especifica el manejador de la API. Expone información como la configuración de todos los routers, servicios, middlewares, etc. Para ver todos los endpoints disponibles se puede consultar la documentación aquí: https://doc.traefik.io/traefik/v2.3/operations/api/#endpoints
La última etiqueta es el middleware básico de autentificación, porque el dashboard de Traefik está expuesto por defecto, así que se añade una capa de seguridad básica sobre él. También protegerá la API.
labels:
- "traefik.enable=true"
- "traefik.docker.network=proxy"
- "traefik.http.routers.traefik-secure.entrypoints=websecure"
- "traefik.http.routers.traefik-secure.rule=Host(`traefik.yourdomain.com`)"
- "traefik.http.routers.traefik-secure.service=api@internal"
- "traefik.http.routers.traefik-secure.middlewares=user-auth@file"