Traefik: LE reverse proxy
Je vous présente dans cette article, comment est installé et configuré Traefik dans notre infra pour orchestrer nos applications docker.
Pour la petite histoire...
Il y a quelques années, en arrivant chez Lucine, j'ai été confronté à une infrastructure en VM VSphere chez OVH.
Pour déployer les applications, nous utilisions des scripts Ansible…
Bon, ça coûtait un bras et c’était pénible de déployer la moindre mise à jour (même si quelques scripts exécutés via SSH étaient de la partie).
Mais j'avais un collègue DSI ouvert d'esprit, avec qui j’ai découvert le reverse proxy Traefik, merci Vincent si tu te reconnais.
Depuis, nous avons dit adieu aux VM, vSphere et OVH (et à Lucine), mais j'ai gardé Traefik en reverse proxy pour tous mes environnements et applications !
Vous l'aurez compris, une fois bien configuré, Traefik gère comme un charme toutes vos applications, avec les certificats SSL automatiques fournis par Let's Encrypt, load balancing et cie...
Docker / Docker compose
Comme beaucoup d'autres comparses, il y a une autre techno que j'apprécie tout particulièrement j'ai nommé Docker.
Depuis quelques années maintenant, je n'ai plus une seule application qui ne soit pas dockerisée. Quelle joie quand on a connu le self-hosting multi-technologies sur VPS, avec Apache, Tomcat, PHP, MySQL... Mais je m'égare, Docker sera le sujet d'autres articles (ou pas, il y en a tellement...).
Revenons à Traefik.
Configuration de base
J'héberge pour ma part mes applications sur un serveur dédié, tournant sous Debian, avec le pare-feu UFW activé. Il ne laisse passé que les ports web (80 et 443), tout deux écouter par Traefik.
J'ai aussi installé un fail2ban, tiens ça aussi il faudra revenir dessus...
Évidement, il faut également un nom de domain, ce sera domain.com
pour l'exemple, fourni par OVH.
Enfin il nous faut également un réseau docker (bridge) pour faire le ... pont ... entre le votre carte réseau et les cartes virtuelles de vos containers.
J'ai pris l'habitude de l'appeler web
, mais vous pouvez l'appeler comme bon vous semble, à condition d'utiliser ce nom dans le reste de vos configurations.
docker network create web
Organisation des applications
Je déploie toutes mes applications via Docker Compose. Pour ce faire, j'ai opté pour une organisation toute simple :
un dossier /app
à la racine de mon disque.
Pour chaque application, un sous-dossier contenant au minimum :
- le
docker-compose.yml
- un
.env
Et parfois un dossier config
pour des configuration spécifique ne passant pas par variables d'environnement et data
pour stocker les données non volatiles.
Et c'est parti pour Traefik.
Je crée donc une dossier /app/traefik
pour accueillir le service.
Et on y met nos fichier docker-compose.yml
et .env
# docker-compose.yml
name: traefik
services:
traefik:
image: traefik:v2.11.5
container_name: traefik
hostname: traefik
restart: unless-stopped
command:
# Setup logger
- --log.level=DEBUG
- --log.filePath=/var/log/traefik/traefik.log
- --accesslog=true
- --accesslog.filepath=/var/log/traefik/access.log
# Enable the Trafik dashboard
- --api.dashboard=true
# Tell Traefik to discover containers using the Docker API
- --providers.docker=true
- --providers.docker.network=web
- --providers.docker.endpoint=unix:///var/run/docker.sock
- --providers.docker.exposedbydefault=false
# Set up LetsEncrypt
- --certificatesresolvers.le.acme.dnschallenge=true
- --certificatesresolvers.le.acme.dnschallenge.provider=ovh
- --certificatesresolvers.le.acme.dnschallenge.delayBeforeCheck=10
- --certificatesresolvers.le.acme.email=admin@domain.com
- --certificatesresolvers.le.acme.storage=/letsencrypt/acme.json
# Set up an insecure listener that redirects all traffic to TLS entrypoint
- --entrypoints.web.address=:80
- --entrypoints.web.http.redirections.entryPoint.to=websecure
- --entrypoints.web.http.redirections.entryPoint.scheme=https
- --entrypoints.web.http.redirections.entrypoint.permanent=true
# Set up the TLS configuration for websecure
- --entrypoints.websecure.address=:443
- --entrypoints.websecure.http.tls=true
- --entrypoints.websecure.http.tls.certResolver=le
environment:
- TZ=Europe/Paris
- OVH_ENDPOINT=ovh-eu
- OVH_APPLICATION_KEY=${APP_OVH_APPLICATION_KEY}
- OVH_APPLICATION_SECRET=${APP_OVH_APPLICATION_SECRET}
- OVH_CONSUMER_KEY=${APP_OVH_CONSUMER_KEY}
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./data/letsencrypt:/letsencrypt
- ./log/traefik:/var/log/traefik
ports:
- '80:80'
- '443:443'
networks:
- web
labels:
- traefik.enable=true
# ADMIN AUTH
- traefik.http.middlewares.admin-auth.basicauth.users=${APP_PASSWORD}
# HTTP ROUTER
- traefik.http.routers.${APP_NAME}.rule=Host(`${APP_DNS}`)
- traefik.http.routers.${APP_NAME}.entrypoints=websecure
- traefik.http.routers.${APP_NAME}.middlewares=admin-auth@docker
- traefik.http.routers.${APP_NAME}.service=api@internal
networks:
web:
external: true
Puis il nous faut les quelques variable d'environnement utilisé dans le composé.
#.env file
APP_NAME=traefik
APP_DNS=traefik.domain.com
APP_PASSWORD=htpassword-type-username-and-password
APP_OVH_APPLICATION_KEY=my-secret-ovh-app-key
APP_OVH_APPLICATION_SECRET=my-secret-ovh-app-secret
APP_OVH_CONSUMER_KEY=my-ovh-consumer-key
Quelques explications:
- On active les logs qui seront dispo dans le dossier
./log/traefik
- Le dashboard (lecture seule) est activé pour monitorer ce qu'il se passe sur le reverse proxy.
Il est sécurisé par un couple user/mdp du typehtpassword
.
https://httpd.apache.org/docs/2.4/fr/programs/htpasswd.html
https://www.web2generators.com/apache-tools/htpasswd-generator - Letsencrypt utilise l'API d'OVH pour confirmer automatiquement la propriété du nom de domaine (ça fonctionne également avec d'autre provider comme GANDI).
- Tout le trafique non sécurisé (http, port 80) est redirigé vers https et les certificats Letsencrypt sont activés par défaut pour toutes les applications.
Les labels docker
C'est LE truc magique qui va vous permettre d'orchestrer vos applications en toute simplicité.
Ici on créer un router appelé traefik (cf .env
) qui va écouter la DNS traefik.domain.com (cf .env
)
Traefik détecte automatiquement le port du service, bien que l'on puisse le spécifier (dans le cas ou par exemple votre container expose plusieurs ports).
# docker-compose.yml
name: traefik
services:
traefik:
image: traefik:v2.11.5
#...
labels:
#...
- traefik.http.routers.${APP_NAME}.service=${APP_NAME}
- traefik.http.services.${APP_NAME}.loadbalancer.server.port=8080
#...
Ces labels vont vous permettre de configurer Traefik, service à service.
Ont y reviendra au fur et a mesure des futurs articles...
Et d'ici là je vous invite évidement à RTFM
https://doc.traefik.io/traefik/getting-started/quick-start/
Démarrage du reverse proxy
Pas de surprise, c'est du docker-compose
docker compose up -d
A partir de là, rendez-vous sur votre DNS et vous devriez voir votre dashboard Trafik
Ajoutons donc un service !
Traefik propose une micro app containerisé très utile pour faire des test.
C'est l'image docker / container whoami.
Si on suit le principe énoncé plus haut, on crée un dossier dans /app
, et on y ajoute un docker-compose.yml
et un fichier .env
(au besoin)
mkdir -p /app/whoami
cd /app/whoami
touch docker-compose.yml .env
# docker-compose.yml
name: whoami
services:
whoami:
image: traefik/whoami
container_name: whoami
hostname: whoami
networks:
- web
labels:
- traefik.enable=true
- traefik.http.routers.${APP_NAME}.rule=Host(`${APP_DNS}`)
- traefik.http.routers.${APP_NAME}.entrypoints=websecure
networks:
web:
external: true
# .env
APP_DNS=whoami.domain.com
APP_NAME=whoami
Conclusion
Et voilà, dans les grandes lignes... Je reviendrai sur différents points au fil des futurs articles.
Mais cette architecture permet d'héberger plutôt facilement pas mal de services (il faut que le serveur tienne la route quand même, je ne ferais pas ça sur un Raspberry Pi 😄).
Vous pouvez maintenant héberger facilement :
- Nextcloud pour faire un cloud ? (on ajoutera quelques middlewares au reverse proxy pour encore plus de sécurité)
- Matrix Synapse et Element pour faire un service de communication sécurisé, privé et chiffré de bout en bout ?
- Bitwarden (vaultwarden) pour fournir un coffre-fort numérique ?
- Gitlab CE pour héberger votre code-base ? Ou juste un Gitlab Runner pour déployer vos applications ?
- Sonarqube pour la qualité
- Ou toutes autre application dockerisé !
En parlant de Gitlab, avec un bonne CI/CD il devient encore plus facile de déployer et mettre à jour vos apps 😎. On en reparle bientôt.
À vos claviers et bon déploiement.