Le but de cette série d’articles est d’utiliser Docker pour mettre en place place Traefik et Portainer pour une utilisation dans un environnement de développement.
Traefik est un reverse proxy qui va diriger les requêtes qu’il reçoit vers différents services. L’idée est de se faciliter la vie en utilisant des urls pour chaque service au lieu de jongler avec des numéros de ports.

Portainer quant à lui est une interface web permettant la gestion de conteneurs Docker. Portainer permet entre autre de déployer et d’arrêter des conteneurs et de créer des applications multi-conteneurs en reprenant la syntaxe des fichiers docker-compose
Pré-requis : Une machine sous linux avec une installation de docker fonctionnelle
On commence par rajouter quelques lignes au fichier /etc/hosts
127.0.0.1 traefik.local portainer.local
127.0.0.1 nginx.dev.local
Dans mon cas, Traefik et Portainer ont chacun une url en .local; les différents projets auront des urls en .dev.local. L’extension .local est prévue pour cet usage et l’ajout au fichier hosts permet de s’affranchir de l’utilisation d »un serveur DNS.
Installation de Traefik
On va commencer par créer un dossier qui contiendra les fichiers de configuration de Traefik ainsi qu’un certificat auto-signé. Vu l’utilisation sur un poste de développement, il n’est pas possible d’utiliser des certificats de Let’s Encrypt.
one@0ne-pc:~/dev$ pwd
/home/one/dev
one@0ne-pc:~/dev$ mkdir traefik
one@0ne-pc:~/dev$ cd traefik/
one@0ne-pc:~/dev/traefik$ touch docker-compose.yml traefik.yml traefik-dynamic.yml
Création du certificat
On crée un sous dossier qui va accueillir le certificat. Il va aussi falloir créer une configuration personnalisée pour OpenSSL, celui ne gérant pas les certificats pour plusieurs noms de domaines (Subject Alternative Names ou SAN).
one@0ne-pc:~/dev/docker$ mkdir certs
one@0ne-pc:~/dev/docker$ cd certs/
one@0ne-pc:~/dev/docker$ touch openssl.conf
Le contenu de openssl.conf
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
x509_extensions = v3_req
prompt = no
[req_distinguished_name]
C = FR
ST = Etat
L = Ville
O = Societe
OU = Service
CN = traefik.local
[v3_req]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = traefik.local
DNS.2 = portainer.local
DNS.3 = dev.local
# certificat wildcard
DNS.4 = *.dev.local
Une fois notre fichier de configuration préparé, on peut générer le certificat et la clé privée associée
one@0ne-pc:~/dev/docker/certs$ openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout traefik.key -out traefik.crt -config openssl.conf
Generating a RSA private key
............................................+++++
........................+++++
writing new private key to 'traefik.key'
-----
one@0ne-pc:~/dev/docker/certs$ openssl x509 -in traefik.crt -text -noout
Si tout s’est bien passé, on a un joli certificat et on peut continuer la configuration de Traefik. Traefik utilise deux fichiers de configurations. Le premier « statique », est chargé au démarrage. Le second « dynamique » est rechargé à chaud. La documentation est là au cas où …
# traefik.yml
api:
dashboard: true
entryPoints:
web:
address: :80
http:
redirections:
entryPoint:
to: websecure
websecure:
address: :443
http:
tls: {}
middlewares:
- secureHeaders@file
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
file:
filename: /etc/traefik/traefik-dynamic.yml
On décompose :
- dashboard : permet d’afficher la webui de Traefik. Elle est désactivée par défaut et si nécessaire on peut la protéger par mot de passe
- entryPoints : points d’entrée de Traefik. Dans mon cas ils s’appellent web pour le port 80 et websecure pour le 443. Il y a aussi une redirection de HTTP vers HTTPS
- providers : indique qu’on va utiliser docker et l’emplacement de la configuration dynamique. Et non, il n’y pas d’erreur dans le chemin du fichier
On passe au fichier de configuration dynamique
# traefik-dyanmic.yml
http:
middlewares:
secureHeaders:
headers:
sslRedirect: true
tls:
certificates:
- certFile: "/etc/traefik/certs/traefik.crt"
keyFile: "/etc/traefik/certs/traefik.key"
stores:
- default
stores:
default:
defaultCertificate:
certFile: "/etc/traefik/certs/traefik.crt"
keyFile: "/etc/traefik/certs/traefik.key"
On peut passer au fichier docker-compose qui va déployer le conteneur Traefik
# docker-compose.yml
version: '3'
services:
traefik:
image: traefik:latest
container_name: traefik
restart: unless-stopped
ports:
- 80:80
- 443:443
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /home/one/dev/docker/traefik.yml:/etc/traefik/traefik.yml
- /home/one/dev/docker/traefik-dynamic.yml:/etc/traefik/traefik-dynamic.yml
- /home/one/dev/docker/certs:/etc/traefik/certs:ro
networks:
- proxy
labels:
- traefik.enable=true
- traefik.docker.network=proxy
- traefik.http.routers.traefik.rule=Host(`traefik.local`)
- traefik.http.routers.traefik.service=api@internal
networks:
proxy:
external: true
Il s’agit d’un fichier docker-compose tout ce qu’il y a de plus classique.
- On prend l’image traefik:latest
- On retrouve nos 2 ports (80 et 443)
- Les différents volumes (socket docker, configs et certificat)
- Des labels pour que Traefik puisse communiquer avec le conteneur
- Un réseau qu’il faudra créer
Les labels vont être lus par Traefik et servent à configurer le service. Chaque label a son importance
- traefik.enable=true # Requis, exposedByDefault défini dans traefik.yml
- traefik.docker.network=proxy # Requis, le nom du network docker
- traefik.http.routers.traefik.rule=Host(`traefik.local`) # Requis, le nom de domaine
- traefik.http.routers.traefik.service=api@internal # documentation de l'api
Traefik va utiliser son propre réseau docker qu’on va appel proxy ici. Il faut d’abord le créer et ensuite on pourra démarrer docker-compose. On omet le -d pour docker-compose pour le moment
one@0ne-pc:~/dev/docker$ docker network create proxy
one@0ne-pc:~/dev/docker$ docker-compose up
Starting traefik ... done
Attaching to traefik
traefik | time="2023-05-05T23:23:23Z" level=info msg="Configuration loaded from file: /etc/traefik/traefik.yml"
Si tout c’est bien passé, vous devriez pouvoir accéder à https://traefik.local

On peut enchainer avec Portainer dans la seconde partie.