Docker: Routage HTTPS

Comment gérer le routage HTTP et le chiffrement TLS (HTTPS) dans vos conteneurs Docker

👋 Bienvenue sur la documentation de Stackhero !

Stackhero propose une solution Docker cloud CaaS (Containers as a Service) prête à l'emploi qui offre de nombreux avantages, notamment :

  • Déployez facilement vos conteneurs en production avec un simple docker-compose up.
  • Nom de domaine personnalisable sécurisé en HTTPS (par exemple, https://api.votre-entreprise.com, https://www.votre-entreprise.com, https://backoffice.votre-entreprise.com).
  • Performance optimale et sécurité renforcée grâce à une VM privée et dédiée.
  • Mises à jour simplifiées en un clic.

Gagnez du temps et simplifiez-vous la vie : il suffit de 5 minutes pour essayer la solution Docker CaaS cloud hosting de Stackhero et déployer vos conteneurs en production !

Chaque instance Stackhero for Docker inclut un serveur Traefik dédié et préconfiguré qui gère le trafic HTTP et le chiffre automatiquement à l'aide de certificats TLS. Cette configuration simplifiée rend le routage simple et efficace. Par exemple :

  • Redirigez le trafic de https://www.my-company.com (avec ou sans le préfixe www) vers votre conteneur frontend.
  • Routez https://www.my-company.com/documentations vers votre conteneur documentations.
  • Dirigez https://api.my-project.io vers votre conteneur api.

Vous pouvez gérer un nombre illimité de domaines avec création et renouvellement automatique des certificats TLS. Le tout, configurable en seulement trois lignes !

Dans tous les exemples de configuration suivants, vous devrez remplacer <XXXXXX>.stackhero-network.com par le nom de domaine de votre instance Stackhero for Docker.

Voici un exemple de base de fichier docker-compose.yml :

services:
  test:
    image: nginx
    labels:
      - "traefik.enable=true" # Active Traefik pour router le trafic vers ce conteneur
      - "traefik.http.routers.test.rule=Host(`<XXXXXX>.stackhero-network.com`)" # Définit le host
      - "traefik.http.routers.test.tls.certresolver=letsencrypt" # Utilise 'letsencrypt' comme résolveur de certificat TLS

Dans cet exemple, un conteneur nommé test utilise l'image Nginx. La configuration clé se trouve dans la section labels. Il vous suffit de copier ces lignes dans votre fichier docker-compose.yml et de remplacer <XXXXXX>.stackhero-network.com par le domaine de votre service.

Vous pouvez déployer le conteneur avec :

docker context use <XXXXXX>.stackhero-network.com
docker-compose up

Après le démarrage du conteneur, rendez-vous sur https://<XXXXXX>.stackhero-network.com/ pour voir la page "Welcome to nginx!".

Page d'accueil NginxPage d'accueil Nginx

Si vous ne voyez pas la page d'accueil Nginx, vérifiez le dashboard Traefik pour d'éventuelles erreurs !

Avec cette configuration, les requêtes HTTP envoyées à <XXXXXX>.stackhero-network.com sont routées vers votre conteneur test et Traefik crée et gère automatiquement les certificats TLS pour HTTPS.

Dans l'exemple précédent, nous avons utilisé le domaine par défaut <XXXXXX>.stackhero-network.com. En pratique, vous utiliserez probablement vos propres domaines d'entreprise ou de projet, comme www.my-company.com ou api.my-project.io. La section ci-dessous explique comment configurer des domaines personnalisés.

Dans cet exemple, vous allez configurer le domaine api.my-project.io. Remplacez my-project.io par un domaine que vous possédez et api par le sous-domaine de votre choix.

Commencez par mettre à jour la configuration DNS de votre domaine afin que api.my-project.io pointe vers votre domaine <XXXXXX>.stackhero-network.com.

  1. Connectez-vous à votre fournisseur de domaine et accédez à la configuration DNS.
  2. Créez une nouvelle entrée nommée api (ou un autre sous-domaine de votre choix), définissez son type sur CNAME et indiquez <XXXXXX>.stackhero-network.com comme destination.

Exemple de configuration DNS sur l'interface Cloudflare DNSExemple de configuration DNS sur l'interface Cloudflare DNS

Une fois le DNS configuré, vous pouvez le valider en exécutant :

host api.my-project.io

Vous devriez obtenir une réponse similaire à :

api.my-project.io is an alias for <XXXXXX>.stackhero-network.com

La propagation DNS peut prendre jusqu'à 24 heures selon votre fournisseur. Si la commande host ne retourne pas la réponse attendue, patientez et réessayez plus tard.

Ensuite, mettez à jour votre fichier docker-compose.yml avec la configuration suivante :

services:
  api:
    image: traefik/whoami
    hostname: api
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.api.rule=Host(`api.my-project.io`)" # Ajoutez votre domaine ici
      - "traefik.http.services.api.loadbalancer.server.port=<PORT>" # Remplacez "<PORT>" par le port sur lequel votre API écoute
      - "traefik.http.routers.api.tls.certresolver=letsencrypt"

N'oubliez pas de remplacer api.my-project.io par votre domaine réel dans le label Traefik Host.

Déployez votre conteneur avec :

docker-compose up -d

Puis rendez-vous sur https://api.my-project.io. Vous devriez voir une page texte affichant le nom d'hôte de votre conteneur api.

Preuve que Traefik gère notre trafic HTTP avec chiffrement TLS pour notre nouveau domainePreuve que Traefik gère notre trafic HTTP avec chiffrement TLS pour notre nouveau domaine

Lors de la première création du conteneur, la génération des certificats TLS peut prendre quelques secondes. Si vous rencontrez une erreur TLS, attendez quelques secondes puis actualisez la page pour laisser le temps aux certificats d'être générés.

Félicitations, vous venez de configurer votre premier domaine personnalisé !

Lorsque vous définissez une URL de site web comme my-company.com, il est recommandé de configurer également un sous-domaine "www". Cela permet aux utilisateurs qui se connectent via www.my-company.com d'être redirigés vers votre site principal et d'éviter les problèmes de contenu dupliqué.

Dans l'exemple ci-dessous, my-company.com et www.my-company.com sont tous deux pris en charge. Les utilisateurs accédant à www.my-company.com sont redirigés vers my-company.com :

services:
  frontend:
    image: traefik/whoami
    hostname: frontend
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.frontend.rule=Host(`my-company.com`) || Host(`www.my-company.com`)" # Ajoutez les deux domaines ici
      - "traefik.http.services.frontend.loadbalancer.server.port=<PORT>" # Remplacez "<PORT>" par le port sur lequel votre frontend écoute
      - "traefik.http.routers.frontend.tls.certresolver=letsencrypt"

      # Redirige 'www.my-company.com' vers 'my-company.com' :
      - 'traefik.http.routers.frontend.middlewares=redirect-www'
      - "traefik.http.middlewares.redirect-www.redirectregex.regex=^https://www.my-company.com/(.*)"
      - "traefik.http.middlewares.redirect-www.redirectregex.replacement=https://my-company.com/$${1}"
      - "traefik.http.middlewares.redirect-www.redirectregex.permanent=true"

Supposons que vous ayez un conteneur dédié à votre site de documentation. Vous pouvez vouloir router https://my-company.com/docs vers ce conteneur, tout en envoyant les autres requêtes, comme https://my-company.com/, vers votre conteneur frontend. L'exemple ci-dessous montre comment procéder :

services:
  documentations:
    image: traefik/whoami
    hostname: documentations
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.documentations.rule=Host(`my-company.com`) && PathPrefix(`/docs`)" # Définissez ici le préfixe de chemin
      - "traefik.http.services.documentations.loadbalancer.server.port=<PORT>" # Remplacez "<PORT>" par le port de votre conteneur documentation
      - "traefik.http.routers.documentations.tls.certresolver=letsencrypt"

  frontend:
    image: traefik/whoami
    hostname: frontend
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.frontend.rule=Host(`my-company.com`) || Host(`www.my-company.com`)"
      - "traefik.http.services.frontend.loadbalancer.server.port=<PORT>" # Remplacez "<PORT>" par le port sur lequel votre frontend écoute
      - "traefik.http.routers.frontend.tls.certresolver=letsencrypt"

      # Redirige 'www.my-company.com' vers 'my-company.com' :
      - 'traefik.http.routers.frontend.middlewares=redirect-www'
      - "traefik.http.middlewares.redirect-www.redirectregex.regex=^https://www.my-company.com/(.*)"
      - "traefik.http.middlewares.redirect-www.redirectregex.replacement=https://my-company.com/$${1}"
      - "traefik.http.middlewares.redirect-www.redirectregex.permanent=true"

Désormais, accéder à https://my-company.com/docs (ou à tout sous-chemin comme https://my-company.com/docs/something) affichera le contenu du conteneur documentations. Les autres chemins, par exemple https://my-company.com/help, seront servis par le conteneur frontend.

Par défaut, Traefik se connecte au premier port exposé du conteneur. Dans certains cas, vous pouvez avoir besoin de spécifier un port particulier. L'exemple ci-dessous montre comment définir un port personnalisé :

services:
  frontend:
    image: traefik/whoami
    hostname: frontend
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.frontend.rule=Host(`my-company.com`)"
      - "traefik.http.routers.frontend.tls.certresolver=letsencrypt"

      # Route le trafic de 'https://my-company.com' vers le conteneur 'frontend' sur le port 80
      - "traefik.http.services.frontend.loadbalancer.server.port=80"

Lorsque vous définissez un conteneur dans votre fichier docker-compose.yml, certains champs sont importants pour plus de cohérence et de simplicité de gestion. Nous vous recommandons la configuration suivante :

services:
  <CONTAINER_NAME>:
    image: traefik/whoami
    hostname: <CONTAINER_NAME>
    container_name: <CONTAINER_NAME>
    restart: unless-stopped
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.<CONTAINER_NAME>.rule=Host(`my-company.com`)"
      - "traefik.http.routers.<CONTAINER_NAME>.tls.certresolver=letsencrypt"

Remplacez simplement <CONTAINER_NAME> par le nom souhaité pour votre conteneur, par exemple frontend.

Lors de la création d'un sous-domaine, Let's Encrypt suit les RFC 952 et 1123, qui autorisent uniquement les caractères du jeu [a-zA-Z0-9-].

Bien que les underscores ('_') soient autorisés dans les noms d'enregistrements DNS, ils ne sont pas acceptés dans les noms d'hôtes. Par conséquent, Let's Encrypt refuse les sous-domaines comme "my_subdomain.example.com" et affiche l'erreur "Domain name contains an invalid character".

Pour corriger ce problème, il suffit de retirer les underscores de vos sous-domaines.