La performance web avec http2

Pourquoi je suis passé en https

J’en avais parlé lors de mon article bilan de début d’année et Google vient d’annoncer qu’à partir de juillet 2018, Google Chrome signalerait à l’internaute le site comme dangereux s’il n’est pas en https : je suis passé en https et donc en http2 pour améliorer les performances !

Docker et Traefik pour passer en https

Pour réaliser cette bascule, j’ai mis en oeuvre le proxy Traefik que j’utilise déjà pour coupler à mes containers Docker.

Gain de performance http vs http2 de mon blog

Avant d’aller plus loin, je vais directement parler de l’amélioration des performances mesurées sur mon blog : j’ai utilisé le site Webpagetest, le gain mesuré est en moyenne de 15% plus rapide en http2 !

Traefik

Træfik est un *proxy applicatif HTTP/HTTPS layer 7, ainsi qu’un loadbalancer qui facilite le déploiement de microservices.

Il supporte plusieurs backends (Docker, Swarm mode, Kubernetes, Marathon, Consul, Etcd, Rancher, Amazon ECS et d’autres), il assure le routage des requêtes vers les backends.

Et cerise sur le gateau il propose nativement une gestion automatique des certificats Letsencrypt.

Fonctionnement et configuration de Traefik

Le fonctionnement est relativement simple, pour cela, il faut configurer des Frontends qui correspondent à des noms de domaine, des routes, avec ou sans expressions régulières. Puis on définie des Backends qui “pointent” vers des containers, urls, …

Exemple de configuration Traefik

J’utilise l’image Docker de Traefik officiel.

http2 web performance avec traefik et letsencrypt

Pour configurer Traefik, il faut créer le fichier traefik.toml de la façon suivante :

  • entryPoints : précise les ports sur lesquels Traefik “écoute” pour moi http et https
  • web : indique le port du dashboard Traefik
  • docker : configure les services qui sont dockerisés et qui ici vont répondre aux requêtes ayant pour nom de domaine serv1.it-wars.com
  • file : permet de définir des frontends et backends qui redirigent les requêtes vers des serveurs virtuels ou baremetals : c’est ici que se trouve la partie concernant mon site web.
  • acme : configuration pour le service LetsEncrypt

Les certificats SSL sont stockés dans le fichier acme.json.

debug = true
checkNewVersion = true
logLevel = "ERROR"
defaultEntryPoints = ["https","http"]

[entryPoints]
  [entryPoints.http]
  address = ":80"
    [entryPoints.http.redirect]
    regex = "^http://(www\\.)?(it-wars\\.com)/(.*)"
    replacement="https://www.$2/$3"
    permanent = true # redirect permanently
  [entryPoints.https]
  address = ":443"
  [entryPoints.https.tls]

[web]
# Port for the status page
address = ":8080"

[docker]
endpoint = "unix:///var/run/docker.sock"
domain = "serv1.it-wars.com" # <-- change this domain
watch = true
exposedbydefault = false

[file]
[backends]
  [backends.web-itwars]
    [backends.web-itwars.servers.server1]
      url = "http://10.0.0.100"
[frontends]
  [frontends.web-itwars]
  entryPoints = ["http", "https"]
  backend = "web-itwars"
  passHostHeader = true
    [frontends.web-itwars.routes.server1]
    rule = "Host: it-wars.com,www.it-wars.com"

[acme]
email = "myemail@gmail.com" # <-- change this email
storage = "acme.json"
entryPoint = "https"
[acme.httpChallenge]
  entryPoint = "http"
OnHostRule = true
[[acme.domains]]
  main = "serv1.it-wars.com"
[[acme.domains]]
  main = "www.it-wars.com"

Composition de service avec Traefik

Dans le fichier docker-compose qui va démarrer ma stack de services, je passe également des paramètres pour Traefik sous la forme de labels. Ici j’ai 3 services qui répondent sur les urls suivants :

  • serv1.it-wars.com
  • serv1.it-wars.com/s1
  • serv1.it-wars.com/s2

version: '2'
services:

  service0:
    image: itwars/webssh
    restart: always
    ports:
      - "8090:8090"
    container_name: service0
    labels:
      - "traefik.backend=service0"
      - "traefik.frontend.rule=Host:serv1.it-wars.com" # <-- Change this domain
      - "traefik.enable=true"
      - "traefik.port=8090"

  service1:
    image: itwars/serv1
    restart: always
    ports:
      - "8091:8091"
    container_name: service1
    labels:
      - "traefik.backend=service1"
      - "traefik.frontend.rule=Host:serv1.it-wars.com;PathPrefixStrip:/s1" # <-- Change this domain
      - "traefik.enable=true"
      - "traefik.port=8091"

  service2:
    image: itwars/service2
    restart: always
    ports:
      - "8092:8092"
    container_name: service2
    labels:
      - "traefik.backend=service2"
      - "traefik.frontend.rule=Host:serv1.it-wars.com;PathPrefixStrip:/s2" # <-- Change this domain
      - "traefik.enable=true"
      - "traefik.port=8092"

  traefik:
     image: traefik
     restart: always
     ports:
       - 80:80
       - 443:443
       - 8080:8080
     volumes:
       - /var/run/docker.sock:/var/run/docker.sock
       - ./traefik.toml:/traefik.toml
       - ./acme.json:/acme.json
     container_name: traefik
     depends_on:
       - service0
       - service1
       - service2

Conclusion sur l’utilisation de Traefik avec Docker et https

J’ulise Traefik depuis quelques temps déjà pour la partie Docker de mon infrastructure, son support natif de Letsecnrypt pour passer mon site web existant en https/http2, a été réalisé en moins de 10 min. Je mesure un gain de performance et je suis maintenant tranquille par rapport à la politique de Google concernant les sites non-https !