Traefik et Docker Compose : comment j'ai bâti une architecture réseau sécurisée pour mes services internes

Traefik et Docker Compose : comment j'ai bâti une architecture réseau sécurisée pour mes services internes

Pourquoi utiliser Traefik comme Reverse Proxy ?

Le problème d'architecture avec Docker

Nous hébergeons souvent plusieurs services sur un même serveur. Un blog Django, un Nextcloud, un Odoo ou un outil de supervision tournent côte à côte.
Chaque application fonctionne dans son conteneur sur un port dédié.

Comment exposer proprement ces services sur Internet avec un seul point d'entrée ?
Comment gérer cela sans ouvrir dix ports différents et sans exposer nos bases de données ?
C'est exactement le problème que résout un reverse proxy.

Les limites d'un Reverse Proxy classique comme Nginx

Avec Nginx en configuration classique, chaque nouveau service demande une intervention manuelle.
On écrit un fichier de configuration, on recharges le service, puis on vérifie les erreurs.

Cette routine devient vite répétitive et génère des erreurs lors des déploiements fréquents.
Par défaut, Nginx ne détecte pas l'apparition d'un nouveau conteneur sur le réseau Docker.

Pourquoi Traefik et Docker Compose changent la donne

Traefik a été conçu pour les environnements conteneurisés.
Il se connecte directement à l'API Docker pour détecter les conteneurs qui démarrent ou s'arrêtent.

Aucun rechargement manuel n'est nécessaire.
On ajoute des labels sur nos conteneurs, Traefik les lit, puis met à jour le routage automatiquement.

L'association avec Docker Compose simplifie la gestion.
Un seul fichier YAML décrit toute notre infrastructure : les services, les réseaux et le routage.

Architecture globale et fonctionnement de Traefik

Les quatre briques fondamentales de Traefik

Traefik s'organise autour de quatre concepts clés :

Découverte automatique des services via le provider Docker

Traefik surveille en permanence le socket Docker.
Lorsqu'un conteneur démarre avec les bons labels, Traefik crée automatiquement son router et son service.
Nous n'avons aucune configuration statique à maintenir pour chaque application.

Le parcours d'une requête HTTP/HTTPS

Voici les étapes traversées par une requête web :

Le conteneur ne reçoit jamais le trafic brut d'Internet.
Il communique uniquement avec la passerelle Traefik.

Guide de configuration Traefik avec Docker Compose

Ces exemples permettent d'illustrer la mise en place.
Il faut adapter les noms de domaine, les réseaux et les versions d'images à votre environnement.

Fichier compose.yml principal pour le Reverse Proxy Traefik

services:
  traefik:
    image: traefik:v3.1
    command:
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"
      - "--certificatesresolvers.letsencrypt.acme.email=ton-email@example.com"
      - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "./letsencrypt:/letsencrypt"
    networks:
      - traefik-net

networks:
  traefik-net:
    driver: bridge

Le paramètre exposedbydefault=false garantit la sécurité.
Il évite d'exposer tous nos conteneurs par défaut.
On doit activer chaque service explicitement avec des labels dédiés.

Automatisation des certificats SSL avec Let's Encrypt

Le résolveur letsencrypt configuré ci-dessus génère nos certificats via le challenge TLS.
Il gère aussi le renouvellement automatique sans intervention humaine.
Nous n'avons plus besoin de surveiller la date d'expiration de nos certificats SSL.

Exposer une application Docker : exemple concret avec Nextcloud

Voici la méthode pour exposer un service comme Nextcloud via des labels Docker :

services:
  nextcloud:
    image: nextcloud:29
    networks:
      - traefik-net
      - nextcloud-internal
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.nextcloud.rule=Host(`cloud.example.com`)"
      - "traefik.http.routers.nextcloud.entrypoints=websecure"
      - "traefik.http.routers.nextcloud.tls.certresolver=letsencrypt"
      - "traefik.http.services.nextcloud.loadbalancer.server.port=80"

networks:
  traefik-net:
    external: true
  nextcloud-internal:
    driver: bridge
    internal: true

L'option internal: true sur le réseau nextcloud-internal est essentielle.
Elle empêche ce réseau d'accéder directement à Internet.

Sécurisation avancée des services internes

Configuration des Middlewares Traefik (Authentification et Rate Limit)

Certains services internes n'ont pas vocation à être totalement publics.
On peut ajouter une couche d'authentification basique sur un tableau de bord :

labels:
  - "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$xxxxxxxx"
  - "traefik.http.routers.netdata.middlewares=auth"

Les mots de passe doivent être générés avec l'outil htpasswd.

Nous pouvons aussi limiter le débit de requêtes pour contrer les attaques par force brute :

labels:
  - "traefik.http.middlewares.limit.ratelimit.average=100"
  - "traefik.http.middlewares.limit.ratelimit.burst=50"

Redirection automatique HTTP vers HTTPS

Le trafic non chiffré doit être proscrit en production.
Nous appliquons une redirection globale au niveau des entrypoints :

command:
  - "--entrypoints.web.http.redirections.entrypoint.to=websecure"
  - "--entrypoints.web.http.redirections.entrypoint.scheme=https"

Toute connexion sur le port 80 est automatiquement basculée sur le port 443.

Isolation des réseaux Docker pour sécuriser les bases de données

C'est la règle d'or pour la sécurité de notre infrastructure.
Chaque application possédant une base de données utilise son propre réseau isolé (internal: true).

Dans notre architecture, MariaDB et Redis restent cantonnés au réseau nextcloud-internal.
PostgreSQL fonctionne uniquement sur odoo-internal.
Aucune base de données n'est connectée au réseau public traefik-net.

En cas de compromission du conteneur Nextcloud, l'attaquant ne peut pas atteindre PostgreSQL.
Ce réseau lui demeure complètement invisible.

Retours d'expérience et conclusion

Gain de temps sur la maintenance d'infrastructure Docker

L'ajout d'un nouveau service ne nécessite plus de modifier la configuration centrale.
Un fichier compose.yml avec des labels valides suffit à déployer une application.
Le gain de temps et la fiabilité sont évidents à mesure que le serveur se remplit.

Impact sur les performances système

Traefik reste très sobre en ressources mémoire et CPU.
La détection dynamique des conteneurs n'ajoute aucune latence mesurable au routage.

Supervision et prochaines étapes

La gestion d'infrastructures demande un suivi constant.
On peut associer Uptime Kuma pour contrôler la disponibilité et Netdata pour surveiller les ressources.

La prochaine étape consistera à automatiser nos alertes et à documenter les plans de reprise d'activité.


EXPERT DEV & OPS

Un projet similaire en vue ?

Besoin d'accompagnement pour développer votre application (React, Django, Laravel), intégrer Odoo ou sécuriser votre infrastructure Linux / Docker ?