Ultimate Docker Home Server avec Traefik 2, LetsEncrypt et OAuth [2020]

Le proxy inverse Traefik 2 avec les services LetsEncrypt et OAuth pour Docker peut être assez difficile. Ce tutoriel détaillé de docker vous montrera comment configurer un Docker Home Server avec Traefik 2, LetsEncrypt et OAuth.

Tout d'abord, aux lecteurs de notre serveur multimédia Docker, du didacticiel Traefik 1 et des guides Traefik Google OAuth, je m'excuse pour le retard. Ce guide est attendu depuis longtemps et je sais que des milliers d'entre vous attendaient avec impatience cette mise à jour.

Remarque: Cet article est co-écrit par Anand et Seth.

Nous allons couvrir la plupart de tout ce qui est nécessaire pour configurer un Docker Home Server avec Traefik 2, Les certificats SSL LetsEncrypt et Google OAuth pour la sécurité. Cependant, fréquemment, nous vous renverrons à mes guides précédents pour une lecture afin de ne pas rendre ce guide trop long.

Cette pile Traefik 2 Docker Home Server est un élément clé de ma configuration de maison intelligente. Alors sans plus attendre, commençons par le guide du serveur Traefik 2 Docker Home.

Il existe plusieurs façons de dépouiller ce chat (Docker Traefik 2) et nous ne sommes en aucun cas un expert. Comme toujours, mon objectif est de partager ce que j'apprends pour que les autres puissent réussir à reproduire ce que j'ai fait. Si vous avez de meilleures idées, n'hésitez pas à les partager dans les sections commentaires.

Objectifs de cette configuration du Traefik 2 Docker Home Server

Mes objectifs pour cette configuration restent à peu près les mêmes que ceux expliqués dans mon guide d'origine du serveur multimédia Docker, avec quelques modifications mineures.

L'une des grandes tâches d'un complètement serveur multimédia automatisé est l'agrégation des médias. Par exemple, lorsqu'un épisode d'émissions télévisées devient disponible, téléchargez-le automatiquement, récupérez son affiche, son fanart, ses sous-titres, etc., mettez-les tous dans un dossier de votre choix (par exemple, dans votre dossier d'émissions télévisées), mettez à jour votre bibliothèque multimédia ( par exemple sur Jellyfin, Emby ou Plex), puis vous envoyer une notification (par exemple, e-mail, notification mobile, etc.) indiquant que votre épisode est prêt à être regardé.

Ça a l'air génial non?

Il existe plusieurs applications qui peuvent effectuer de telles tâches et nous les avons compilées dans notre liste des meilleures applications de serveur domestique.

Voici un résumé de certaines des applications que je voulais que mon serveur domestique Docker exécute:

  • Parties avant: Traefik, Portainer, Organizr, Heimdall
  • Maison intelligente: HA-Dockermon, Mosquitto MQTT Broker, ZoneMinder, MiFlora Plant Sensors
  • Bases de données: MariaDB, phpMyAdmin, InfluxDB, Postgres, Grafana
  • Téléchargeurs: téléchargeur, Transmission Bittorrent avec VPN, SABnzbd, qBittorrent avec VPN
  • Indexeurs: NZBHydra2, Jackett
  • PVR: Lidarr, Radarr, Sonarr, LazyLibrarian
  • Serveurs multimédias: Airsonic, Plex, Emby, Jellyfin, Ombi, Tautulli, PhotoShow, Calibre et plus
  • Gestion des fichiers multimédias: Bazarr, Picard, Frein à main, MKVToolNix, MakeMKV, FileBot, etc.
  • Utilitaires système: Firefox, Regards, APCUPSD, Logarr, Guacamole, Dozzle, qDirStat, StatPing, SmokePing, et plus encore.
  • Entretien: Ouroboros et Docker-GC

J'ai également utilisé Home Assistant sur Docker, mais je suis maintenant passé à HASSio sur Docker. Pour la liste à jour des applications que j'exécute à l'aide de ma configuration Docker Traefik 2, veuillez consulter mon référentiel GitHub.

En plus des objectifs énumérés dans mon article d'origine sur le serveur multimédia Docker, je veux que ma configuration Traefik 2 Docker Home Server offre les éléments suivants:

  • Fournir des services de base de données pour toutes les autres applications à utiliser
  • Fournir des utilitaires tels que VNC, RDP, SSH, accès aux fichiers à distance, surveillance des services et plus encore pour simplifier ma vie
  • Rendez toutes les applications accessibles en toute sécurité sur Internet sans avoir à rediriger sur le routeur
  • Offrez un moyen facile d'accéder aux applications en utilisant des noms de domaine conviviaux au lieu de ports
  • Offrez un niveau de sécurité plus élevé puisque les applications seront exposées à Internet

Cela peut sembler une configuration complexe, mais croyez-moi, docker, avec Docker Compose peut faciliter l'installation et la maintenance de ces applications de serveur domestique.[[Lis: 9 Meilleures options de logiciel de serveur de musique: créez votre propre Spotify]

Configuration requise pour cette configuration Docker Traefik 2

Plusieurs conditions doivent être remplies avant de poursuivre ce didacticiel Docker pour la configuration de microservices derrière le proxy inverse Traefik.

1. Serveur domestique

Un serveur multimédia domestique est un serveur situé dans votre réseau domestique qui agit comme un dispositif central de stockage et de distribution de données. En règle générale, un serveur domestique est toujours allumé, a des tonnes de capacité de stockage et prêt à servir des fichiers (y compris les médias) lorsque le besoin s'en fait sentir.

Nous avons couvert plusieurs sujets sur les serveurs domestiques dans les détails ci-dessus. Pour certaines versions supplémentaires de serveurs domestiques, je suggère les messages suivants:

Builds HTPC / Home Server recommandés:

2. Système d'exploitation

Une fois que vous avez compris le matériel, la prochaine grande question est le système d'exploitation. À mon avis, Linux est le meilleur système d'exploitation sur lequel construire votre serveur multimédia domestique.[[Lis: 10 meilleures discothèques Linux Home Server – stabilité, performances, facilité d'utilisation]

Nous avons toujours recommandé Ubuntu Server, plus spécifiquement les LTS (Long Term Support Releases), qui sont pris en charge pendant 5 ans. Une fois que vous avez construit votre serveur, vous pouvez le laisser fonctionner pendant 5 ans avec toutes les mises à jour de sécurité de l'équipe Ubuntu.

Meilleures applications de serveur domestique pour automatiser la gestion des médias

L'année dernière, je suis passé d'Ubuntu Server à Linux Mint sur le serveur Intel NUC Home. Docker a rendu le passage de Sever Edition (Ubuntu) à Desktop Edition (Linux Mint) très facile.

Tout ce que j'avais à faire était d'installer Linux Mint, d'installer Docker et Docker Compose et de démarrer la pile. Toutes mes applications ont été lancées.[[Lis: Passer d'un serveur domestique à un NAS (Synology) – Le pourquoi, les enseignements et les conseils]

Nous avons testé ce guide sur Ubuntu Server 18.04 LTS et Linux Mint 19.1. La prochaine version à long terme 20.04 Focal Fossa approche à grands pas. Nous mettrons à jour ce guide peu de temps après sa publication.

Cela dit, cette Serveur d'accueil Traefik v2 Docker peut être suivi sur tout système d'exploitation pouvant exécuter Docker. Cela inclut même les périphériques de stockage en réseau tels que Synology. Nous avons testé avec succès ce guide sur mon Synology DS918 + avec Docker et Docker Compose (nous le couvrirons dans un guide séparé).

3. Nom de domaine

Dans mon guide Traefik 1, j'ai discuté du sujet du DNS dynamique par rapport à votre propre nom de domaine.

Avec les services DNS dynamiques gratuits (DuckDNS, Afraid.org, etc.), vous devrez utiliser la structure d'URL du sous-répertoire (si vous voulez garder les choses pratiques / simples). D'un autre côté, avoir votre propre nom de domaine donne beaucoup plus de flexibilité et de confidentialité.

Un nom de domaine privé ne coûte qu'environ 7 $ XX par an avec Cloudflare et je le recommande fortement. Par souci de simplicité, nous rédigeons ce guide pour les noms de domaine privés.

Si vous avez un DNS dynamique gratuit avec DuckDNS ou Afraid.org, vous devrez combiner ce qui est présenté dans ce guide Docker Traefik avec mon guide précédent sur Traefik 1 pour créer vos étiquettes Docker Compose.

4. Enregistrements DNS appropriés

En plus d'avoir un nom de domaine privé, vous devrez avoir des enregistrements DNS corrects avec votre registraire de domaine.

Mon fournisseur DNS est Cloudflare, qui est testé et vérifié pour fonctionner avec les certificats génériques Traefik LetsEncrypt. Si votre fournisseur DNS n'est pas répertorié comme pris en charge, je recommande de déplacer votre DNS vers Cloudflare, qui est incroyablement rapide et gratuit.

Sur Cloudflare, vous devez pointer votre domaine racine (example.com) vers votre IP WAN en utilisant un enregistrement A. Ensuite, ajoutez un CNAME générique (* .example.com) ou des sous-domaines individuels, tous pointant vers votre domaine racine (@ pour l'hôte), comme indiqué ci-dessous (cela ne nécessite pas de compte payant).

Entrées DNS Cloudflare pour Traefik 2 DNS Challenge

Entrées DNS Cloudflare pour Traefik 2 DNS Challenge

En plus de créer les enregistrements DNS, vous devrez ajuster les paramètres SSL de Cloudflare pour éviter les redirections indéfinies. Aller à SSL / TLS paramètres pour le domaine et modifier SSL à Plein comme indiqué ci-dessous.

Cloudflare

SSL "complet" Cloudflare pour la configuration Docker de Traefik 2

Remarque: Vous devrez peut-être attendre quelques minutes pour que les entrées DNS se propagent. Si vous exécutez Traefik avant cela, le défi DNS peut échouer et aucun certificat SSL ne sera généré. Si vous continuez à essayer, Let's Encrypt peut vous interdire temporairement d'avoir atteint les limites de demande. Pour contrer cela, je propose d'utiliser le serveur de transfert LetsEncrypt pour la validation initiale et les tests, comme expliqué plus loin dans ce guide docker traefik.

5. Transfert de port pour Traefik 2.0

Enfin, vous devez activer la redirection de port sur votre routeur ou passerelle.

Traefik Reverse Proxy utilise les ports 80 et 443. Le trafic reçu sur ces ports depuis Internet doit être transféré vers l'adresse IP interne / locale de l'hôte docker exécutant le service Traefik 2.

Configuration de Docker

Le prochain gros composant est Docker. Si vous avez suivi notre précédent guide du serveur multimédia Docker, vous devriez avoir couvert la plupart de ce sujet. Cependant, au cours des deux dernières années depuis la publication de notre guide, nous avons apporté plusieurs modifications et améliorations mineures.

Pour la plupart des détails, nous vous renverrons à notre message d'origine. Nous mettrons en évidence certaines des principales améliorations et différences et ici.

Qu'est-ce que Docker?

Nous avons déjà couvert ce qu'est Docker et comment il se compare à une machine virtuelle telle que VirtualBox. De plus, un bref aperçu de Docker a été présenté dans mon guide précédent.

Docker vs machines virtuelles fabriquées par docker

Docker vs machines virtuelles fabriquées par docker

Docker permet d'installer des applications en tant que conteneurs isolés des systèmes d'exploitation hôtes. Mais les conteneurs partagent les ressources système. La virtualisation (par exemple, VirtualBox, VMware, etc.), d'autre part, exécute des systèmes isolés "complets", chacun nécessitant sa propre maintenance.

Docker permet de créer et de détruire des applications en quelques secondes, sans gâcher le système hôte. Les conteneurs démarrent également en quelques secondes et votre application est donc prête à rouler très rapidement.

Guides recommandés:

Qu'est-ce que Docker Compose?

Compose est un outil pour créer une liste de tous les conteneurs (ainsi que leur configuration) que vous souhaitez exécuter. Il est écrit en YAML. Les conteneurs Docker peuvent être créés à partir de la ligne de commande à l'aide de diverses commandes. Docker-compose le rend encore plus facile.

Une fois que votre fichier de composition est prêt, avec une seule commande, vous pouvez créer, démarrer ou arrêter vos applications à la fois.

Docker rend également les applications plus portables. Lorsque je suis passé de mon ancien serveur domestique à Intel NUC, j'étais opérationnel sur mon nouveau serveur avec plus de 50 applications en moins en 15 minutes.

Dans ce guide Docker Traefik 2, nous utiliserons Docker Compose pour créer notre serveur domestique Docker Traefik.

Pourquoi utiliser Docker pour configurer un serveur domestique?

La manière traditionnelle de construction d'un serveur domestique implique la configuration du système d'exploitation, l'ajout de référentiels, le téléchargement des applications, l'installation des prérequis / dépendances, l'installation de l'application et la configuration de l'application. C'est lourd et non portable.

Nous avons créé AtoMiC ToolKit, qui automatise l'installation et la maintenance des applications de serveur domestique sous Linux. Mais Docker rend les choses si faciles que nous avons maintenant abandonné AtoMiC ToolKit et sommes passés à Docker et Docker Compose.

Rechercher des applications conteneurisées sur Docker Hub

Rechercher des applications conteneurisées sur Docker Hub

Dans Docker, les applications de serveur domestique telles que Sonarr, Radarr, Plex, etc. peuvent être installées facilement sans se soucier des prérequis ou des incompatibilités. Toutes les exigences sont déjà pré-emballées avec chaque image de conteneur.

La plupart des applications bien connues sont déjà conteneurisées par la communauté Docker et disponibles via le Docker Hub.

MISE EN GARDE: Assurez-vous d'utiliser l'image du conteneur à partir d'une source fiable pour des raisons de sécurité. Les images présentant des vulnérabilités peuvent compromettre votre système.

Installer Docker et Docker Compose

Docker est disponible pour Linux, Mac OS et Windows 10. Nous avons précédemment couvert diverses procédures d'installation de Docker et Docker Compose:

Voici quelques ressources supplémentaires pour divers systèmes d'exploitation:

Vous devez avoir Docker et Docker Compose en cours d'exécution avant de continuer avec ce guide Docker Traefik v2.

Configuration de Docker

L'exécution de commandes Docker sous Linux nécessite sudoen d'autres termes, élévation des privilèges d'administrateur. Vous pouvez contourner cela en ajoutant l'utilisateur Linux (vous-même) au groupe Docker comme expliqué dans mon guide Docker d'origine.

Certains considèrent que vous ajouter au groupe Docker constitue un risque pour la sécurité. C'est vrai, mais le risque est considérablement atténué en faisant attention et en utilisant des conteneurs de confiance.

Créer un dossier racine Docker et définir des autorisations

Si vous avez suivi mes précédents guides Docker, vous devriez déjà avoir le répertoire suivant sur les systèmes Linux. Ce sera notre dossier racine de docker:

/ accueil / UTILISATEUR / docker

UTILISATEUR est votre nom d'utilisateur. Sinon, créons ce dossier (qui hébergera toutes vos données de services docker et vos fichiers .yml) à l'aide de la commande suivante:

mkdir ~ / docker

Ensuite, laissez-nous configurer les autorisations appropriées sur le dossier Docker pour éviter tout problème d'erreur d'autorisation. Utilisez les commandes suivantes dans l'ordre:

sudo setfacl -Rdm g: docker: rwx ~ / docker
sudo chmod -R 775 ~ / docker

La commande ci-dessus force tous les nouveaux sous-dossiers du dossier Docker à hériter des autorisations du dossier Docker. Certains peuvent être en désaccord avec les autorisations libérales ci-dessus, mais encore une fois, c'est pour un usage domestique et c'est assez restrictif.

Configuration des variables d'environnement pour Docker et Docker Compose

Nous allons mettre certaines informations fréquemment utilisées dans un emplacement commun et les appeler au besoin en utilisant des noms de variables. C'est ce que la définition de variables environnementales signifie en termes simples.

Dans mes précédents tutoriels Docker et Traefik v1, ces informations sont entrées dans le / etc / environnement fichier. Cela a nécessité une déconnexion et une connexion pour prendre effet.

Dans ce nouveau guide Docker Traefik 2.0, nous allons prendre un itinéraire différent. Toutes les variables environnementales vont entrer dans un .env fichier qui se trouvera dans le dossier racine du docker créé à l'étape précédente.

Créez le .env fichier (Remarque: le point devant n'est pas une faute de frappe) dans le dossier racine du docker (/home/USER/docker/.env) et ajoutez-y les variables d'environnement suivantes:

PUID = 1000
PGID = 140
TZ = "America / New_York"
USERDIR = "/ home / USER"

Remplacer / configurer:

  1. PUID et PGID – l'ID utilisateur de l'utilisateur linux, sur lequel nous voulons exécuter les applications du serveur domestique, et l'ID de groupe de docker. Ces deux éléments peuvent être obtenus à l'aide du id comme indiqué ci-dessous.
    ID utilisateur et ID de groupe

    ID utilisateur et ID de groupe

    Dans ce guide, nous allons utiliser 1000 pour PUID, qui est l'ID utilisateur de l'utilisateur et 140, qui est l'ID de groupe du groupe docker.

  2. TZ – le fuseau horaire que vous souhaitez définir pour vos conteneurs. Obtenez votre TZ à partir de cette base de données de fuseau horaire.
  3. USERDIR – le chemin d'accès au dossier de départ de l'utilisateur actuel. Vous pouvez également l'obtenir à l'aide de la commande suivante:
    cd ~; pwd
    

Ces variables environnementales seront appelées $ VARIABLE_NAME tout au long du fichier docker-compose. Leurs valeurs seront automatiquement extraites du fichier d'environnement que nous avons créé / édité ci-dessus.

Au fur et à mesure que nous parcourons ce guide Traefik 2, nous continuerons à ajouter plus de variables environnementales au .env fichier. Vous en trouverez un exemple .env dans mon référentiel GitHub lié ci-dessous.

Voilà, le travail de préparation de base pour construire notre serveur d'accueil Docker est terminé.

Commandes Docker de base à connaître

Avant de nous lancer, apprenons quelques commandes de base à utiliser via ce guide Docker Traefik v2. La plupart des commandes ont été discutées en détail dans mon précédent guide du serveur Docker.

Ce que nous allons présenter ici est une manière simplifiée d'utiliser ces commandes en utilisant bash_aliases sur les systèmes Ubuntu / Linux.

Un exemple .bash_aliases fichier est fourni dans mon dépôt GitHub.

Vous trouverez ci-dessous certaines des commandes de raccourci que vous pouvez utiliser pour effectuer plusieurs opérations liées au docker et à la composition du docker à partir de la ligne de commande.

Alias ​​/ raccourcis pour les commandes Docker

  • dstopcont SERVICENAME – stop conteneur
  • dstopall – arrêter tous les conteneurs en cours d'exécution
  • docdf – stockage utilisé par docker
  • docps – liste de tous les conteneurs

Alias ​​/ raccourcis pour les commandes Docker Compose

  • dcup2 – démarrer la pile de composition Docker de Traefik 2
  • dcdown2 – arrêtez toute la pile de composition du docker Traefik 2
  • dcrec2 SERVICENAME – recréer un service spécifique à partir de Docker Traefik 2 copose
  • dcrestart2 SERVICENAME – redémarrer un conteneur spécifique
  • dcpull2 – mettre à jour toutes les images de conteneurs

Certains des alias répertoriés ci-dessus ne concernent que Traefik v2.0. Il existe beaucoup plus de commandes de raccourcis (alias), pour inclure Traefik v1.0, que celles répertoriées ci-dessus. Consultez donc l'exemple de fichier bash_aliases lié ci-dessus.

Ceci termine la partie de configuration et de préparation du docker. Passons maintenant à la configuration de Traefik 2.0.

Configuration de Traefik 2

Contrairement à mon précédent guide Traefik, nous n'allons pas vous montrer les exemples de composition de docker pour toutes les quelque 50 applications que j'exécute. Au lieu de cela, mon approche avec ce guide Traefik 2 est de vous montrer comment configurer Traefik 2 et quelques applications comme exemples.

Les exemples d'applications que j'ai choisis présenteront diverses possibilités avec Traefik 2 et couvriront certains scénarios courants. Vous pouvez les utiliser comme exemples et adapter les exemples de composition de docker pour d'autres applications.

Remarque: Mon GitHub Repo et ce guide sont créés de telle manière que Traefik 1 et Traefik 2 puissent coexister dans le même dossier racine de docker. Mais un seul (Traefik 1 ou 2) peut être exécuté à tout moment et proxy les services. Par distinction, les fichiers / dossiers liés à Traefik v1 one auront t1 et ceux liés Traefik 2 auront t2 en leurs noms.

Présentation de Traefik Reverse Proxy

Traefik reverse proxy fournit la commodité et la sécurité de vos services accessibles sur Internet (par exemple, Radarr, Sonarr, SABnzbd, etc.). Un serveur proxy inverse se trouve généralement derrière un pare-feu (routeur ou passerelle Internet) et dirige les clients vers les applications appropriées en utilisant un nom commun (radarr.example.com) sans que le client ait à connaître l'adresse IP ou le port du serveur. Le client interagit avec le proxy inverse et le proxy inverse dirige la communication vers l'application principale pour fournir / récupérer des informations.

Docker Traefik Guide - Schéma du proxy inverse

Schéma du proxy inverse

Les informations de base sur le proxy inverse ont déjà été couvertes en détail dans mon précédent tutoriel Traefik. Voici les liens vers les sections pertinentes pour votre examen:

En bref, nous allons utiliser Traefik principalement pour:

  • Mettez nos applications derrière une URL pratique et facile à retenir
  • Ajoutez une authentification de base ou Google OAuth 2.0 pour une autre couche de sécurité pour les applications
  • Ajouter des en-têtes de sécurité pour les interfaces Web des applications
  • Réduisez les risques de sécurité en évitant la redirection de port vers des applications individuelles (sans les exposer directement à Internet)
  • Mettez tous nos services derrière les certificats SSL LetsEncrypt qui sont automatiquement extraits et renouvelés par Traefik 2

Dans mon guide précédent, j'ai discuté de deux façons d'accéder à vos applications à partir d'Internet: le sous-répertoire et le sous-domaine.

Dans ce guide, par souci de commodité, nous allons seulement vous montrer la méthode de sous-domaine avec un nom de domaine privé. Si vous souhaitez utiliser la méthode du sous-répertoire, vous pouvez combiner les informations de mon guide précédent pour comprendre les choses.

Traefik 1 vs Traefik 2

Traefik 2 a introduit de nombreux changements de rupture. Beaucoup de visiteurs qui ont suivi mon guide précédent se sont réveillés un matin et ont constaté que leur configuration était cassée car leur configuration avait automatiquement été mise à jour du jour au lendemain vers Traefik 2.

Ma configuration Traefik 1 fonctionnait parfaitement. Alors pourquoi passer à Traefik 2? Passons un peu de temps à comprendre Traefik 2 avant de commencer à configurer notre serveur domestique Docker Traefik 2.

Migration de Traefik v1 vers v2 – Faits saillants

Les développeurs de Traefik et la communauté ont fourni un excellent guide de migration Traefik 1 vers 2. Mais voici quelques faits saillants pertinents.

  1. Traefik version 2 a une syntaxe et un format différents pour sa configuration, ce qui signifie que le docker-compose.yml et traefik.toml utilisé pour Traefik 1.7.X ne peut pas être utilisé avec la dernière version de Traefik.
  2. Vous pouvez choisir la version avec les balises docker, en utilisant les balises disponibles répertoriées sur DockerHub (et ici: liste des versions de traefik avec leurs balises). Afin de rester à jour avec la dernière version, je recommande d'utiliser la balise de sortie pour chaque version.
    • chevrotin = 2.2.X
    • cantal = 2.1.X
    • maroilles = 1.7.X
  3. Traefik v1.7 n'est plus en cours de développement, mais recevra toujours les mises à jour de sécurité nécessaires en utilisant la balise maroilles. Tout au long de ce guide, nous utiliserons la dernière balise pour Traefik v2.2 – chevrotin. Toutes les futures mises à jour de la version 2.2 de Traefik peuvent ensuite être automatiquement mises à jour avec un service comme Watchtower ou Ouroboros.
  4. Bien que Traefik version 2 nécessite une nouvelle configuration, j'ai constaté qu'il utilise un grand nombre des mêmes concepts que la version 1.7. Voici certains des concepts qui, selon moi, ont une meilleure définition et un meilleur objectif dans la v2:

    Parallèlement à ces concepts améliorés, quelques nouvelles fonctionnalités, telles que:

    • Routeurs
    • Middlewares
    • Prestations de service
    • Routage TCP

    Si vous ne comprenez rien de tout cela, ne vous inquiétez pas. Nous vous dirons ce que vous devez savoir pour démarrer le serveur Docker Traefik 2.

Pourquoi passer à Traefik 2?

La principale raison de la mise à niveau vers Traefik 2 était la prise en charge améliorée des en-têtes, mais j'ai trouvé que ce que j'aimais le plus était la façon dont la version 2 utilise les middlewares.

Cela a considérablement simplifié ma configuration et il est désormais extrêmement facile de configurer de nouveaux itinéraires et services. Vous pouvez également réutiliser la même configuration, ce qui vous permet de mettre à jour plusieurs services en modifiant un fichier de configuration.

J'ai passé beaucoup trop de temps avec la v1 pour m'assurer que chaque service était à jour avec toutes les améliorations que j'avais apportées.

Nous allons passer à travers tout cela ensemble et j'espère que vous voyez les mêmes grands avantages que moi.

Routeurs, middlewares et services Traefik 2

Traefik v1 a utilisé deux concepts principaux lors de la gestion des demandes: les frontends et les backends. Les frontends identifieraient et modifieraient le traitement de la demande, tandis que les backends identifieraient où envoyer la demande. Traefik v2 n'utilise plus ces définitions et, à la place, trois composants doivent être définis dans le cadre de notre configuration: routeurs, services et middlewares.

    Fournisseur Traefik

    Présentation de Traefik Providers

    Routeurs

    Les routeurs sont comme des frontends, ils gèrent les requêtes entrantes. Dans la section routeurs, vous allez définir le point d’entrée, le résolveur de certificats et définir les règles de la demande.

    Prestations de service

    Les services sont comme des backends, ils identifient où envoyer les demandes. C'est ici que vous pouvez définir le port vers lequel Traefik sera proxy et tout équilibreur de charge supplémentaire.

    Middlewares

    Les middlewares sont l'une des nouvelles fonctionnalités intéressantes de Traefik v2. Les middlewares modifient la requête, et en effet ils sont le "middleware" entre les routeurs et les services. Dans la v1, les middlewares ont été définis sur le frontend, mais la séparation de ces fonctionnalités nous donne une flexibilité et une commodité supplémentaires. Vous pouvez facilement ajouter des éléments tels que des en-têtes, l'authentification, le préfixe de chemin ou les combiner et créer des groupes réutilisables.

    Avec ces trois concepts, nous pouvons identifier la demande entrante, définir où va la demande et choisir comment nous voulons modifier la demande au fur et à mesure de son acheminement.

    Débuter avec Traefik v2

    Voici quelques conseils que je recommande lors de la configuration de Traefik 2.0 pour, espérons-le, faciliter les choses un peu:

  • Rester simple: Parfois, il peut être difficile de résoudre le problème lorsque beaucoup de choses ont changé en même temps. Commencez avec un exemple de base et accédez d'abord au tableau de bord Traefik, puis continuez à ajouter des services à partir de là.
  • Tableau de bord Traefik / Auth API requis: Le tableau de bord Traefik doit être protégé par authentification, sinon vous devrez utiliser l'indicateur non sécurisé. En suivant ce guide, nous aurons une configuration sécurisée et nous n'aurons pas besoin d'utiliser cet indicateur.
  • Allez au formatage: Traefik est écrit en Go, et nous devons donc utiliser le formatage Go en fonction du type d'entrée (chaîne, booléen, tableau). Cela signifie, par exemple, que votre nom d'hôte doit être défini avec des backticks, tels que `traefik.example.com` (les apostrophes ne fonctionneront pas!).

Cela complète la plupart des informations de base dont vous pourriez avoir besoin. Passons à la configuration de Traefik 2 avec Docker.

Configuration de Traefik 2

Il existe plusieurs façons de configurer Traefik 2 et cela peut être assez écrasant pour les débutants. Même avec une certaine expérience, j'ai parfois du mal à comprendre les méthodes de configuration de Traefik 2.

Prenons donc le temps de comprendre certains détails importants de la configuration de Traefik 2: configuration statique vs configuration dynamique.

Configurations statiques et dynamiques pour Traefik v2

Présentation de la configuration de Traefik 2

Configuration dynamique

Traefik est un proxy inverse dynamique, ce qui signifie qu'il peut ajouter et supprimer automatiquement des itinéraires au démarrage ou à l'arrêt des conteneurs. Les étiquettes attachées à chaque conteneur du docker-compose.yml, par exemple, font partie de la configuration dynamique de Traefik.

Vous pouvez également router vers des hôtes supplémentaires dans le cadre de votre configuration dynamique si vous les avez définis avec le fournisseur de fichiers (que nous avons arbitrairement appelé rules.toml dans notre guide Traefik v1).

Notez que nous pourrions définir notre configuration dynamique 1) avec notre fournisseur Docker en utilisant des étiquettes, et 2) avec notre fournisseur de fichiers.

Configuration statique

Bien que les méthodes dynamiques soient l'un des principaux avantages de Traefik, il est important de comprendre que Traefik utilise également une configuration statique qui est définie différemment, et doit être séparé.

Il existe trois façons différentes de définir la configuration statique pour Traefik 2. Une seule peut être utilisée en même temps.

  1. Fichier de configuration – peut être dans un fichier TOML ou YAML (par exemple, traefik.toml ou traefik.yaml).
  2. Arguments de ligne de commande (CLI) – ces arguments sont passés pendant docker run
  3. En tant que variables d'environnement – voici une liste de toutes les variables d'environnement.

Ces moyens sont évalués dans l'ordre indiqué ci-dessus.

Dans notre guide Traefik v1, nous avons défini la plupart de notre configuration statique à l'aide d'un traefik.toml fichier. La configuration statique est lue au démarrage de Traefik et ne peut pas être modifiée pendant l'exécution.

Dans ce guide, nous allons simplifier un peu les choses en configurant Traefik version 2 sans traefik.toml fichier. Au lieu de cela, nous allons tirer parti de la méthode des arguments CLI listée ci-dessus. Cela nous donne un fichier de moins à craindre et combine notre configuration de fournisseur Docker en un seul fichier Docker-compose.

Travaux préparatoires pour Traefik 2

Ensuite, faisons un travail de préparation pour que le conteneur Traefik v2 Docker soit opérationnel. Nous allons utiliser la même structure de dossiers que celle utilisée pour notre guide du serveur multimédia Docker.

Créer des informations d'authentification HTTP de base

Bien que l'objectif de ce post soit d'utiliser Google OAuth 2, vous avez la possibilité d'utiliser l'authentification HTTP de base si vous le souhaitez. Pour cela, nous devons créer un .htpasswd fichier avec les informations de connexion.

Nous allons mettre ce fichier dans $ USERDIR / docker / partagé dossier. Utilisez ce générateur HTPASSWD pour créer un nom d'utilisateur et un mot de passe et les ajouter au $ USERDIR / docker / shared / .htpasswd fichier comme indiqué ci-dessous:

nom d'utilisateur: mystrongpassword

Remplacer / configurer:

  1. Nom d'utilisateur: avec votre nom d'utilisateur HTTP.
  2. mystrongpassword: avec votre mot de passe HTTP haché généré en utilisant le lien ci-dessus.
Notez que si vous placez le nom d'utilisateur et le mot de passe dans le fichier Docker compose directement plutôt que dans le fichier d'environnement, $ les signes du mot de passe haché doivent être échappés en ajoutant un autre $ signé devant. Par exemple:

utilisateur: $ apr1 $ bvj3f2o0 $ / 01DGlduxK4AqRsTwHnvc1

Devrait être:

utilisateur: $$ apr1 $$ bvj3f2o0 $$ / 01DGlduxK4AqRsTwHnvc1

Dans le fichier d'environnement, les signes $ n'ont pas besoin d'être échappés.

Alternativement, vous pouvez utiliser la commande suivante sous Linux pour générer un nom d'utilisateur et un mot de passe déjà échappés:

echo $ (htpasswd -nb nom d'utilisateur mystrongpassword) | sed -e s / \ $ / \ $ \ $ / g

Enregistrez le fichier et quittez.

Créer des variables environnementales Traefik 2

Nous avons déjà ajouté plusieurs variables d'environnement pour docker dans les étapes précédentes.

Maintenant, ouvrez le même .env fichier et ajoutez les nouvelles variables suivantes:

DOMAINNAME = example.com
[email protected]
CLOUDFLARE_API_KEY = XXXXXXXXXXXX

Remplacer / configurer:

  1. exemple.com: Votre nom de domaine DNS privé ou dynamique.
  2. [email protected]: Courriel de votre compte cloudflare. Ceci n'est requis que si vous effectuez des tests DNS Challenge pour les certificats Wildcard Traefik Letsencrypt.
  3. XXXXXXXXXXXX: Clé API de votre compte cloudflare (API globale clé de la page Profil. Pas le ID de zone ou identifiant de compte). Encore une fois, cela n'est nécessaire que pour DNS Challenge pour exécuter des applications sous des sous-domaines.
    Clé API globale Cloudflare pour le défi DNS

    Clé API globale Cloudflare pour Let's Encrypt DNS Challenge

Comme expliqué précédemment, dans ce guide, nous utiliserons la méthode DNS Challenge pour que Traefik obtienne des certificats génériques de LetsEncrypt. Pour ce faire, avec Cloudflare, nous avons besoin des deux variables ci-dessus définies (CLOUDFLARE_EMAIL et CLOUDFLARE_API_KEY).

Cryptons la liste des fournisseurs DNS Traefik Wildcard

Cryptons la liste des fournisseurs DNS Traefik Wildcard

Si vous utilisez l'un des autres fournisseurs DNS au lieu de Cloudflare, assurez-vous d'inclure les paramètres de configuration requis dans le fichier de variables d'environnement.

Préparer les dossiers et fichiers Traefik 2

Ensuite, nous devons créer de nouveaux dossiers pour Traefik et ACME dans le dossier racine du docker ($ USERDIR / docker) décrit précédemment:

mkdir traefik2
mkdir traefik2 / acme

traefik2 est le dossier que nous utiliserons pour stocker toutes les configurations liées à Traefik 2.0.

Docker ne peut pas créer de fichiers manquants (uniquement les répertoires). Nous devrons donc créer un fichier vide pour Traefik pour stocker notre certificat LetsEnrypt. Ainsi, à partir du dossier racine du docker, créez acme.json fichier vide à l'aide de la commande suivante:

touchez traefik2 / acme / acme.json

Ensuite, définissez l'autorisation appropriée pour acme.json fichier à l'aide de la commande suivante:

chmod 600 traefik2 / acme / acme.json

le acme.json Le fichier stockera tous les certificats SSL générés. Dans les étapes ultérieures de ce guide, il vous sera demandé d'ouvrir et de vérifier ce fichier.

De même, nous allons créer un fichier journal dans lequel Traefik pourra écrire des journaux. À partir du dossier racine de docker, créons un fichier journal vide:

touchez traefik2 / traefik.log

Créer un réseau proxy Traefik 2

La dernière étape consiste à créer un réseau pour le proxy inverse Traefik 2 à utiliser, à l'aide de la commande suivante:

réseau docker créer t2_proxy

Alternativement, si vous souhaitez définir votre propre sous-réseau, vous pouvez utiliser la commande suivante:

docker network create --gateway 192.168.90.1 --subnet 192.168.90.0/24 t2_proxy

Personnaliser 192.168.90.0/24 en fonction de votre situation. La commande ci-dessus permet d'utiliser la plage IP 192.168.90.1 à 192.168.90.254 (254 IP) pour vos services de docker.

Comme indiqué plus loin, vous pouvez définir des adresses IP statiques pour vos services si nécessaire.

Traefik 2 Docker Compose

Toutes les informations de base ont été présentées et le travail de préparation a été effectué. Commençons par ce que vous attendiez tous. Création du fichier Traefik 2 Docker Compose.

Définir des réseaux dans Docker Compose

Créez un fichier appelé docker-compose-t2.yml dans le dossier racine de docker dont nous avons parlé plus haut dans ce guide (même emplacement que .env fichier, $ USERDIR / docker). Nous commencerons par y ajouter ce qui suit:

Mise en garde: Faites attention aux espaces vides dans les exemples de composition de docker ci-dessous. L'espacement est très important pour YAML lire correctement vos fichiers.

version: "3.7"

########################### RÉSEAUX
réseaux:
  t2_proxy:
    externe:
      nom: t2_proxy
  défaut:
    pilote: pont

########################### PRESTATIONS DE SERVICE
prestations de service:
# Tous les services / applications vont en dessous de cette ligne

Ajouter Traefik 2 et Traefik 2 Dashboard

Tiens bon, ça va être long. Mais ne vous inquiétez pas, nous le ferons en morceaux.

Tout d'abord, ajoutons les bases du service Traefik 2:

# Traefik 2 - Proxy inverse
  traefik:
    nom_conteneur: traefik
    image: traefik: chevrotin # la balise chevrotin fait référence à v2.2.x
    redémarrage: à moins qu'il ne soit arrêté

Rien d'extraordinaire ici. Ensuite, nous ajouterons nos arguments CLI pour configurer Traefik 2.0. La plupart des paramètres utilisés auparavant traefik.toml dans notre guide Traefik 1 ira ici à la place.

        commande: # arguments CLI
      - --global.checkNewVersion = true
      - --global.sendAnonymousUsage = true
      - --entryPoints.http.address =: 80
      - --entryPoints.https.address =: 443
        # Autorisez ces IP à définir les en-têtes X-Forwarded- * - IP Cloudflare: https://www.cloudflare.com/ips/
      - --entrypoints.https.forwardedHeaders.trustedIPs=173.245.48.0/20,103.21.244.0/22,103.22.200.0/22,103.31.4.0/22,141.101.64.0/18,108.162.192.0/18,190.93.240.0/20,188.114.96.0/20,197.234.240.0/22,198.41.128.0/17,162.158.0.0/15,104.16.0.0/12,172.64.0.0/13,131.0.72.0/22
      - --entryPoints.traefik.address=:8080
      - --api=true
#      - --api.insecure=true
#      - --serversTransport.insecureSkipVerify=true
      - --log=true
      - --log.level=DEBUG # (Default: error) DEBUG, INFO, WARN, ERROR, FATAL, PANIC
      - --accessLog=true
      - --accessLog.filePath=/traefik.log
      - --accessLog.bufferingSize=100 # Configuring a buffer of 100 lines
      - --accessLog.filters.statusCodes=400-499
      - --providers.docker=true
      - --providers.docker.endpoint=unix:///var/run/docker.sock
      - --providers.docker.defaultrule=Host(`{{ index .Labels "com.docker.compose.service" }}.$DOMAINNAME`)
      - --providers.docker.exposedByDefault=false
      - --providers.docker.network=t2_proxy
      - --providers.docker.swarmMode=false
      - --providers.file.directory=/rules # Load dynamic configuration from one or more .toml or .yml files in a directory.
#      - --providers.file.filename=/path/to/file # Load dynamic configuration from a file.
      - --providers.file.watch=true # Only works on top level files in the rules folder
      - --certificatesResolvers.dns-cloudflare.acme.caServer=https://acme-staging-v02.api.letsencrypt.org/directory # LetsEncrypt Staging Server - uncomment when testing
      - --certificatesResolvers.dns-cloudflare.acme.email=$CLOUDFLARE_EMAIL
      - --certificatesResolvers.dns-cloudflare.acme.storage=/acme.json
      - --certificatesResolvers.dns-cloudflare.acme.dnsChallenge.provider=cloudflare

The above Traefik v2.0 CLI arguments are what goes into a traefik.toml (or YAML) file if you decided to use one.

Here are some important lines that will require your attention:

–entrypoints.https.forwardedHeaders.trustedIPs

When using Cloudflare and all your traffic is behind their proxy (orange cloud in the DNS records), the request's origin IP is replaced with Cloudflare's IP. The result is that all of your services will know that a Cloudflare IP has connected, but you can't see the actual origin IP. This line tells Traefik to trust forwarded headers information (X-Forwarded-*) for the publicly available Cloudflare IPs, which basically means that Traefik will accept the X-Forwarded-For header set by Cloudflare.

This option is not needed if you are not using Cloudflare's proxy features (DNS entries are grey-clouded).

–api.insecure=true

This line is commented out because we are going to put Traefik 2 dashboard behind authentication. If you, for whatever reason, do not want to enable authentication then uncomment this line by removing the # in front.

–serversTransport.insecureSkipVerify=true

I recommend leaving this line disabled (commented out), which will default to "false". Certain apps that require HTTPS for their web UI can be finicky behind Traefik (eg. NextCloud, Unifi Controller). If you set insecureSkipVerify to true this disables SSL certificate verification, so we want to avoid this if possible. We can use TCP routers (discussed later in the guide) that will allow us to access services like Nextcloud and Unifi Controller that require HTTPS.

–log.level=DEBUG

Start out by setting this to DEBUG. Once you ensure everything is working fine and LetsEncrypt Certificates are being pulled correctly, you can change this to WARN.

–providers.file.directory=/rules

As in our Traefik 1 guide, we are going to use a rules folder instead of a rules.toml fichier. In this folder, we will store some configurations that Traefik 2 can pick up in real-time (if –providers.file.watch est réglé sur true), without needing a restart. Examples include, middlewares, configurations for proxying external or non docker-apps, etc. Some example rules and scenarios are discussed later in this Docker Traefik 2 tutorial.

–providers.file.filename=/path/to/file

This line is commented out because we are not going to use rules.toml. Instead, we are going to use a rules folder, which is enabled in the previous line of the configuration.

–certificatesResolvers.dns-cloudflare.acme Lines

Now we are going to talk about the last 5 CLI arguments:

            - --certificatesResolvers.dns-cloudflare.acme.caServer=https://acme-staging-v02.api.letsencrypt.org/directory # LetsEncrypt Staging Server - uncomment when testing
      - --certificatesResolvers.dns-cloudflare.acme.email=$CLOUDFLARE_EMAIL
      - --certificatesResolvers.dns-cloudflare.acme.storage=/acme.json
      - --certificatesResolvers.dns-cloudflare.acme.dnsChallenge.provider=cloudflare
      - --certificatesResolvers.dns-cloudflare.acme.dnsChallenge.resolvers=1.1.1.1:53,1.0.0.1:53

This is where we define our certificate resolver(s). In this guide, we're using the ACME DNS challenge with Cloudflare as our provider, so I've chosen dns-cloudflare as the name for this cert resolver. If you are using another ACME challenge or DNS verification provider other than Cloudflare you may want to name your cert resolver differently.

caServer: This is a very important line. When enabled, we will be using the LetsEncrypt staging server to check if everything is working fine. As mentioned previously, LetsEncrypt has a rate limit to prevent system abuse. In case you have errors in your Traefik 2 Docker Compose, you may be locked out of LetsEncrypt validation. To prevent this, we will use the staging server for the initial setup. Once we ensure everything is working well (shown later) we will comment out this line and have Traefik 2 get the real LetsEncrypt SSL certificates from the default server.

Nothing to change with email ou storage. For Cloudflare, make sure your environmental variable ($CLOUDFLARE_EMAIL) is set. Other providers may have different requirements and may not require an email.

provider: Change if you use a provider other than Cloudflare for DNS challenge.

Networks for Traefik 2 Dashboard

Next comes the network block. You can either let Docker assign a dynamic IP for the traefik service or manually assign a static IP.

        networks:
      t2_proxy:
        ipv4_address: 192.168.90.254 # You can specify a static IP
#    networks:
#      - t2_proxy

The example above is for a static IP on the Docker network of 192.168.90.254. This IP is only accessible by the host and on the Docker network. If you want Docker to assign the container IP dynamically, comment out the first three lines and uncomment the last two.

Setting a static IP is helpful for some services like databases (MariaDB, InfluxDB, etc.) or whenever one of your containers needs to refer to another statically. For example, my PiHole can connect to Unbound using it's static Docker IP instead of exposing any ports to the host.

Security Options

The security options block allows us to set some additional security parameters. For example, using the block below, we can limit container processes from gaining additional privileges.

        security_opt:
      - no-new-privileges:true

In case you are interested, here are several more Docker security configurations.

Traefik 2 Ports

Next, we are going to specify the port information for Traefik 2. Traefik needs three ports: 80, 443, and 8080. The last one is needed for Traefik 2 Dashboard.

        ports:
      - target: 80
        published: 80
        protocol: tcp
        mode: host
      - target: 443
        published: 443
        protocol: tcp
        mode: host
      - target: 8080
        published: 8080
        protocol: tcp
        mode: host

As you can see, ports for Traefik 2 are the same as for Traefik 1.

Traefik 2 Volumes

Here are the volumes that I have specified in my Traefik 2 docker-compose file:

        volumes:
      - $USERDIR/docker/traefik2/rules:/rules 
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - $USERDIR/docker/traefik2/acme/acme.json:/acme.json 
      - $USERDIR/docker/traefik2/traefik.log:/traefik.log 
      - $USERDIR/docker/shared:/shared

le rules volume contains the configuration for our File provider (eg. middlewares, rules for external/non-docker apps). More on these later in this Traefik 2 docker guide.

As explained previously, I use the partagé folder to share some common information between various services. Remember that we also placed the Basic HTTP authentication credentials in this folder.

The rest of the volumes/files can be used as-is.

Traefik Environmental Variables

We are going to pass two additional environmental variables for Traefik 2 service to use:

        environment:
      - CF_API_EMAIL=$CLOUDFLARE_EMAIL
      - CF_API_KEY=$CLOUDFLARE_API_KEY

Tous les deux $CLOUDFLARE_EMAIL et $CLOUDFLARE_API_KEY, which were set previously set using .env file will be passed on to CF_API_EMAIL et CF_API_KEY, respectively, for DNS challenge verification.

Traefik 2 Docker Labels

The last one is a big one: labels for Traefik 2. This is the part that has completely changed in docker-compose for Traefik 2, compared to Traefik 1.

First, is the line to enable or disable traefik for services. Quite simple.

        labels:
      - "traefik.enable=true"

When the container starts a route will automatically be created. This is necessary because we’ve specified exposedByDefault=false as part of our static configuration.

Next, we add the routers to redirect all HTTP traefik to the secure HTTPS port:

            # HTTP-to-HTTPS Redirect
      - "traefik.http.routers.http-catchall.entrypoints=http"
      - "traefik.http.routers.http-catchall.rule=HostRegexp(`{host:.+}`)"
      - "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"

Then, we add additional routers for entrypoints, certificate resolving, and domain information:

            # HTTP Routers
      - "traefik.http.routers.traefik-rtr.entrypoints=https"
      - "traefik.http.routers.traefik-rtr.rule=Host(`traefik.$DOMAINNAME`)"
      - "traefik.http.routers.traefik-rtr.tls=true"
      - "traefik.http.routers.traefik-rtr.tls.certresolver=dns-cloudflare" # Comment out this line after first run of traefik to force the use of wildcard certs
      - "traefik.http.routers.traefik-rtr.tls.domains[0].main=$DOMAINNAME"
      - "traefik.http.routers.traefik-rtr.tls.domains[0].sans=*.$DOMAINNAME"
#      - "traefik.http.routers.traefik-rtr.tls.domains[1].main=$SECONDDOMAINNAME" # Pulls main cert for second domain
#      - "traefik.http.routers.traefik-rtr.tls.domains[1].sans=*.$SECONDDOMAINNAME" # Pulls wildcard cert for second domain

By default, Traefik will listen for incoming requests on all available entrypoints. You can limit or specify an entrypoint if you’d like to do so. In the above case, Traefik will listen on only HTTPS (secure entrypoint).

le rule is how we define which requests this router will apply to. The majority of my containers use the Host(`FQDN`) rule, but you could use regex, pathprefix or other options as well. le rule has to follow Go formatting, which means that we need to use backticks around string values, not apostrophes!

Avec tls, we are explicitly stating that this router should connect via TLS, and should not accept HTTP connections.

Take a note of the certresolver label. After initial testing and first Traefik run to pull LetsEncrypt wildcard certificates, we will have to comment out this line to force usage of wildcard certificates and stop creating separate certificates for individual services.

I’ve chosen arbitrary names to help describe their function, for example, I’ve chosen dns-cloudflare because I’m using the DNS challenge and Cloudflare is my provider. The name can be changed to anything, but it must be the same as the certresolver we defined in our CLI arguments.

You'll also notice I'm using different names for each router, for example, the HTTP-to-HTTPS Redirect router is arbitrarily named 'http-catchall' and the HTTP Router is 'traefik-rtr'. Routers are grouped using these names, but the name can be changed as you like to describe the router.

In the example above, we are using only one domain ($DOMAINNAME and its wildcard *.$DOMAINNAME). To define additional domains, uncomment the last two lines. Assure-toi $SECONDDOMAINNAME is set in your .env fichier. You can specify additional domains using domains[2], domains[3], etc. Traefik will pull SSL certificates for all of these domains.

The last part of the labels is a big one: middlewares. This will specify the security headers, set authentication, etc. First, let's start simple and then add additional labels.

If you do not want to set authentication for Treafik 2 dashboard (remember to enable –api.insecure=true) then all that is needed here is the following line to specify where the service to be proxied is available:

            ## Services - API
      - "[email protected]"

The Traefik dashboard/API is a special case and should be defined exactly as [email protected]. We will do this differently for the rest of the services in this guide.

If you start your Traefik 2 service now, then we should be in business. However, remember that we are not going to make Traefik v2 dashboard accessible without authentication.

Traefik 2 Basic HTTP Authentication

First, let us set the simplest form of authentication and get things to work properly. This is where middlewares come into play.

Let's create our first middleware using our File provider. Create a file named middlewares.toml inside the Traefik 2 rules folder ($USERDIR/docker/traefik2/rules) and add the following content to it:

[http.middlewares]
  [http.middlewares.middlewares-basic-auth]
    [http.middlewares.middlewares-basic-auth.basicAuth]

#      username=user, password=mystrongpassword (listed below after hashing)
#      users = [
#        "user:$apr1$bvj3f2o0$/01DGlduxK4AqRsTwHnvc1",
#      ]
      realm = "Traefik2 Basic Auth"
      usersFile = "/shared/.htpasswd" #be sure to mount the volume through docker-compose.yml

The above code block adds a basic authentication middleware. We can specify users for authentication right here if you wish (the commented-out lines).

But as discussed previously, we are going to use .htpasswd file to store our credentials. So we will specify the path to usersFile.

Now let us add this middleware to our Traefik 2.0 un service. This requires defining the middlewares we want to use on our router.

            ## Middlewares
      - "trae[email protected]file" 

We are basically asking Traefik to look for the middlewares-basic-auth middleware that we defined with our File provider (@file) in the rules dossier.

Using the @ symbol to specify the provider is a new feature in Traefik v2, but it is required in order to identify the source of the middleware. If no provider is specified, then Traefik assumes the source of the middleware is the current provider (@docker).

Note that the underlined part here middlewares-basic-auth@file matches the underlined name in [httpmiddlewares[httpmiddlewaresmiddlewares-basic-auth] dans le middlewares.toml file we created previously.

Testing Docker Traefik 2 Setup

So far, our docker-compose-t2.yml file should look something like this:

version: "3.7"

########################### NETWORKS
networks:
  t2_proxy:
    external:
      name: t2_proxy
  default:
    driver: bridge

########################### SERVICES
prestations de service:
# All services / apps go below this line

# Traefik 2 - Reverse Proxy
  traefik:
    container_name: traefik
    image: traefik:chevrotin # the chevrotin tag refers to v2.2.x
    restart: unless-stopped
    command: # CLI arguments
      - --global.checkNewVersion=true
      - --global.sendAnonymousUsage=true
      - --entryPoints.http.address=:80
      - --entryPoints.https.address=:443
        # Allow these IPs to set the X-Forwarded-* headers - Cloudflare IPs: https://www.cloudflare.com/ips/
      - --entrypoints.https.forwardedHeaders.trustedIPs=173.245.48.0/20,103.21.244.0/22,103.22.200.0/22,103.31.4.0/22,141.101.64.0/18,108.162.192.0/18,190.93.240.0/20,188.114.96.0/20,197.234.240.0/22,198.41.128.0/17,162.158.0.0/15,104.16.0.0/12,172.64.0.0/13,131.0.72.0/22
      - --entryPoints.traefik.address=:8080
      - --api=true
#      - --api.insecure=true
#      - --serversTransport.insecureSkipVerify=true
      - --log=true
      - --log.level=DEBUG # (Default: error) DEBUG, INFO, WARN, ERROR, FATAL, PANIC
      - --accessLog=true
      - --accessLog.filePath=/traefik.log
      - --accessLog.bufferingSize=100 # Configuring a buffer of 100 lines
      - --accessLog.filters.statusCodes=400-499
      - --providers.docker=true
      - --providers.docker.endpoint=unix:///var/run/docker.sock
      - --providers.docker.defaultrule=Host(`{{ index .Labels "com.docker.compose.service" }}.$DOMAINNAME`)
      - --providers.docker.exposedByDefault=false
      - --providers.docker.network=t2_proxy
      - --providers.docker.swarmMode=false
      - --providers.file.directory=/rules # Load dynamic configuration from one or more .toml or .yml files in a directory.
#      - --providers.file.filename=/path/to/file # Load dynamic configuration from a file.
      - --providers.file.watch=true # Only works on top level files in the rules folder
      - --certificatesResolvers.dns-cloudflare.acme.caServer=https://acme-staging-v02.api.letsencrypt.org/directory # LetsEncrypt Staging Server - uncomment when testing
      - --certificatesResolvers.dns-cloudflare.acme.email=$CLOUDFLARE_EMAIL
      - --certificatesResolvers.dns-cloudflare.acme.storage=/acme.json
      - --certificatesResolvers.dns-cloudflare.acme.dnsChallenge.provider=cloudflare
      - --certificatesResolvers.dns-cloudflare.acme.dnsChallenge.resolvers=1.1.1.1:53,1.0.0.1:53
    networks:
      t2_proxy:
        ipv4_address: 192.168.90.254 # You can specify a static IP
#    networks:
#      - t2_proxy
    security_opt:
      - no-new-privileges:true
    ports:
      - target: 80
        published: 80
        protocol: tcp
        mode: host
      - target: 443
        published: 443
        protocol: tcp
        mode: host
      - target: 8080
        published: 8080
        protocol: tcp
        mode: host
    volumes:
      - $USERDIR/docker/traefik2/rules:/rules 
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - $USERDIR/docker/traefik2/acme/acme.json:/acme.json 
      - $USERDIR/docker/traefik2/traefik.log:/traefik.log 
      - $USERDIR/docker/shared:/shared
    environment:
      - CF_API_EMAIL=$CLOUDFLARE_EMAIL
      - CF_API_KEY=$CLOUDFLARE_API_KEY
    labels:
      - "traefik.enable=true"
      # HTTP-to-HTTPS Redirect
      - "traefik.http.routers.http-catchall.entrypoints=http"
      - "traefik.http.routers.http-catchall.rule=HostRegexp(`{host:.+}`)"
      - "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
      # HTTP Routers
      - "traefik.http.routers.traefik-rtr.entrypoints=https"
      - "traefik.http.routers.traefik-rtr.rule=Host(`traefik.$DOMAINNAME`)"
      - "traefik.http.routers.traefik-rtr.tls=true"
      - "traefik.http.routers.traefik-rtr.tls.certresolver=dns-cloudflare" # Comment out this line after first run of traefik to force the use of wildcard certs
      - "traefik.http.routers.traefik-rtr.tls.domains[0].main=$DOMAINNAME"
      - "traefik.http.routers.traefik-rtr.tls.domains[0].sans=*.$DOMAINNAME"
#      - "traefik.http.routers.traefik-rtr.tls.domains[1].main=$SECONDDOMAINNAME" # Pulls main cert for second domain
#      - "traefik.http.routers.traefik-rtr.tls.domains[1].sans=*.$SECONDDOMAINNAME" # Pulls wildcard cert for second domain
      ## Services - API
      - "[email protected]"
      ## Middlewares
      - "trae[email protected]file" 

Note that "certresolver=dns-cloudflare" in the labels should match what is specified in "–certificatesResolvers.dns-cloudflare.acme…." in the Traefik 2 CLI arguments.

At this point, let's save the file and start Traefik 2. From the docker root folder, run:

docker-compose -f docker-compose-t2.yml up -d

Alternatively, you can use either dcup2 ou dcrec2 traefik bash_aliases shortcuts to start Traefik 2.

Immediately, let's start following the logs for Traefik service to look for any obvious errors. Use the following command or the shortcut dclogs2 traefik. Again, from the docker root folder run:

docker logs -tf --tail="50" traefik

Here are some messages that show that everything went well:

  • Waiting for DNS record propagation
  • The server validated our request
  • Validations succeeded, requesting certificates
  • Server responded with a certificate

At this point, if you see any "bad certificate" or "unknown certificate" messages, ignore them. Remember that we are using LetsEncrypt staging server, which does not provide valid certificates yet.

There are multiple ways to check if Traefik 2 is configured correctly and succeeded in obtaining LetsEncrypt certificate. We'll show you two of them here.

Let's open Traefik 2 dashboard in a browser and see the certificate information, as shown below. Remarquez le Fake LE Intermediate X1. This shows that an SSL (fake) certificate was obtained by Traefik 2 from LetsEncrypt staging server.

Traefik 2.0 Successful Staging Shows Fake LE Intermediate Certificate

Traefik 2.0 Successful Staging Shows Fake LE Intermediate Certificate

Alternatively, you can open acme.json file located inside the traefik2 folder ($USERDIR/docker/traefik2/acme/acme.json) and look for signs of successful validation, as shown below.

acme.json File for Staged Traefik 2.0 LetsEncrypt Domain Validation

acme.json File for Staged Traefik 2.0 LetsEncrypt Domain Validation

If you have been successful so far, then congratulations. You are ready to get real now.

Fetching Real LetsEncrypt Wildcard Certificates using Traefik 2

Since our staging was successful, let us now open the docker-compose-t2.yml file and comment out the following line (as shown below) so that we can reach the real LetsEncrypt server for DNS challenge.

#      - --certificatesResolvers.dns-cloudflare.acme.caServer=https://acme-staging-v02.api.letsencrypt.org/directory 

Save the Traefik v2 docker-compose file.

Ouvrez le acme.json file, delete all contents, and save it. Alternatively, you may delete acme.json file and recreate an empty file (remember to set the right permissions as described previously).

Next, recreate Traefik (dcrec2 traefik or the full command listed previously), and follow the logs (dclogs2 traefik or the full command listed previously) once again to make sure everything goes smoothly.

DNS Challenge Traefik 2 Logs Showing Successful Certificate Retrieval from LetsEncrypt

DNS Challenge Traefik 2 Logs Showing Successful Certificate Retrieval from LetsEncrypt

The logs look good without any errors. Now let us check the certificates in the browser to verify the SSL certificate.

Final LetsEncrypt SSL Certificate using Traefik Reverse Proxy

Final LetsEncrypt SSL Certificate using Traefik Reverse Proxy

Cela semble bon. Notice that the certificate includes both example.com and the wildcard *.example.com. Let us also check the acme.json fichier.

acme.json File for Final Traefik 2.0 LetsEncrypt Domain Validation

acme.json File for Final Traefik 2.0 LetsEncrypt Domain Validation

Notice that it does not say "staging" anymore. So all good so far and our Docker Traefik 2 stack is coming along quite well.

Forcing the Use of Wildcard Certs

Now that the wildcard certificates have been pulled, let us force Traefik to use that (*.example.com certificate) instead of creating a separate certificate for each service (service.example.com).

To do this, comment out the certresolver in the docker-compose file as shown below.

#      - "traefik.http.routers.traefik-rtr.tls.certresolver=dns-cloudflare"

Recreate your traefik 2.0 service and check to make sure the dashboard is accessible.

Securing Traefik 2 Dashboard

Now that everything is working great, let us start improving the security of our services. We already added some security with the basic authentication middleware.

Here are a few more you can add.

Rate Limit

The rate limit middleware ensures that services will receive a fair number of requests. This is helpful if intentionally (eg. security breach) or unintentionally your services are being bombarded with requests causing a denial of service situation.

We are going to open the middlewares.toml file we created above and add the rate limit middleware just as we did for basic authentication. Add the following lines below what we already added for basic authentication (pay attention to the spacing/formatting).

  [http.middlewares.middlewares-rate-limit]
    [http.middlewares.middlewares-rate-limit.rateLimit]
      
      average = 100
      burst = 50

Now we can add this middleware to Traefik 2 dashboard the same way we added the basic authentication middleware – by modifying the middlewares label in docker compose as follows:

            - "trae[email protected]file,[email protected]" 

Note that I added rate-limiting as the first line of defense.

Security Headers

In our Traefik 1 docker-compose, we had several browser security headers. Let us start adding those to our Traefik 2 services. You can add them as labels (like in our Traefik 1 docker-compose file) or as middleware using the File provider.

As you would see later in this guide, using the File provider for middlewares significantly reduces the size of docker-compose files by avoiding repetitions and reusing code.

Security Headers as Labels

Let us add the security header middlewares to what we already have in our labels. Notice that we will be creating a new name for this middleware traefik-headers simply by adding the label "traefik.http.middlewares….". Adding these labels to the Docker container will define the middleware, but you also need to add the middleware to the router, traefik-rtr (traefik.http.routers.traefik-rtr.middlewares=…).

In this middleware I don’t have an “@” included and only call the middleware as traefik-headers. By default, Traefik is assuming that this means [email protected], which would be correct since we are defining the middleware in our "Docker provider" as labels, and not in our File provider.

            ## Middlewares
      - "traefik.http.routers.traefik-rtr.middlewares=traefik-headers,[email protected],[email protected]"
      - "traefik.http.middlewares.traefik-headers.headers.accesscontrolallowmethods=GET, OPTIONS, PUT"
      - "traefik.http.middlewares.traefik-headers.headers.accesscontrolalloworiginlist=https://$DOMAINNAME"
      - "traefik.http.middlewares.traefik-headers.headers.accesscontrolmaxage=100"
      - "traefik.http.middlewares.traefik-headers.headers.addvaryheader=true" 
      - "traefik.http.middlewares.traefik-headers.headers.allowedhosts=traefik.$DOMAINNAME" 
      - "traefik.http.middlewares.traefik-headers.headers.hostsproxyheaders=X-Forwarded-Host"
      - "traefik.http.middlewares.traefik-headers.headers.sslredirect=true"
      - "traefik.http.middlewares.traefik-headers.headers.sslhost=traefik.$DOMAINNAME" 
      - "traefik.http.middlewares.traefik-headers.headers.sslforcehost=true"
      - "traefik.http.middlewares.traefik-headers.headers.sslproxyheaders.X-Forwarded-Proto=https"
      - "traefik.http.middlewares.traefik-headers.headers.stsseconds=63072000"
      - "traefik.http.middlewares.traefik-headers.headers.stsincludesubdomains=true"
      - "traefik.http.middlewares.traefik-headers.headers.stspreload=true"
      - "traefik.http.middlewares.traefik-headers.headers.forcestsheader=true"
      - "traefik.http.middlewares.traefik-headers.headers.framedeny=true"
#      - "traefik.http.middlewares.traefik-headers.headers.customframeoptionsvalue=SAMEORIGIN" # This option overrides FrameDeny
      - "traefik.http.middlewares.traefik-headers.headers.contenttypenosniff=true"
      - "traefik.http.middlewares.traefik-headers.headers.browserxssfilter=true"
#      - "traefik.http.middlewares.traefik-headers.headers.contentsecuritypolicy=frame-ancestors 'none'; object-src 'none'; base-uri 'none';"
      - "traefik.http.middlewares.traefik-headers.headers.referrerpolicy=same-origin"
      - "traefik.http.middlewares.traefik-headers.headers.featurepolicy=camera 'none'; geolocation 'none'; microphone 'none'; payment 'none'; usb 'none'; vr 'none';"
      - "traefik.http.middlewares.traefik-headers.headers.customresponseheaders.X-Robots-Tag=none,noarchive,nosnippet,notranslate,noimageindex,"

Please note that explaining what these security headers do is outside the scope of this post, which is already turning out to be one of the longest posts I have ever written. You can read more about traefik security headers here.

What is provided here should work for most of you and for most services.

You can add the same set of security headers to all your other services/apps and modify them as you like. Be sure to change traefik-headers et traefik.$DOMAINNAME" (allowedhosts et sslhost).

Security Headers as Middlewares File

As you can see there are a lot of options for security headers that we can add. With Traefik 1 we would have to copy these for each service, but Traefik 2 makes this really easy. Instead of using those labels, we can move them all to our middlewares file and call them into our docker-compose file as we did for rate limit and basic authentication.

Ouvert middlewares.toml again and add the following lines below what we've already added (change example.com (3 instances)):

  [http.middlewares.middlewares-secure-headers]
    [http.middlewares.middlewares-secure-headers.headers]
      
      accessControlAllowMethods= ["GET", "OPTIONS", "PUT"]
      accessControlMaxAge = 100
      hostsProxyHeaders = ["X-Forwarded-Host"]
      sslRedirect = true
      stsSeconds = 63072000
      stsIncludeSubdomains = true
      stsPreload = true
      forceSTSHeader = true
#      frameDeny = true #overwritten by customFrameOptionsValue
      customFrameOptionsValue = "allow-from https:example.com" #CSP takes care of this but may be needed for organizr. 
      contentTypeNosniff = true 
      browserXssFilter = true 
#      sslForceHost = true # add sslHost to all of the services
#      sslHost = "example.com"
      referrerPolicy = "same-origin" 
#      Setting contentSecurityPolicy is more secure but it can break things. Proper auth will reduce the risk.
#      the below line also breaks some apps due to 'none' - sonarr, radarr, etc.
#      contentSecurityPolicy = "frame-ancestors '*.example.com:*';object-src 'none';script-src 'none';"
      featurePolicy = "camera 'none'; geolocation 'none'; microphone 'none'; payment 'none'; usb 'none'; vr 'none';" 
      [http.middlewares.middlewares-secure-headers.headers.customResponseHeaders]
        X-Robots-Tag = "none,noarchive,nosnippet,notranslate,noimageindex,"
        server = ""

While adding security headers via a middleware file simplifies the Traefik 2.0 docker-compose file, it does come with limitations compared to using labels. Notice that the lines sslForceHost et sslHost have been commented out.

These two options add a little bit more security but unfortunately will break apps. En effet, le sslHost option requires a specific hostname (eg. service.example.com) and therefore one cannot provide a universal host that will apply to all services that will use Traefik 2.

Remarque: You cannot add only sslForceHost et sslForceHost as labels in docker-compose and leave the rest in the middleware file.

What is provided as labels will completely overwrite what is provided in the middlewares file. At this point, it looks like Traefik 2 does not append the two. So the only options are to either exclude those two lines (very slight decrease in security for convenience) or specify all security headers in the docker-compose files as labels (long docker-compose files). I chose to exclude (comment-out) those two lines in the middlewares.toml fichier.

As with other middlewares provided in the file, we now have to include this middleware in the compose file by modifying the line as follows:

            - "traefik.[email protected]file,[email protected],[email protected]" 

As always, recreate the services after any changes to the docker-compose file.

Middleware Chains

There is a simpler way to provide middlewares than specifying each of them individually. We can create what is known as "middleware chains". A Chain is simply a group of middlewares.

Create a file called middleware-chains.toml dans le rules folder and add the following lines:

[http.middlewares]
  [http.middlewares.chain-no-auth]
    [http.middlewares.chain-no-auth.chain]
      
      middlewares = [ "middlewares-rate-limit", "middlewares-secure-headers"]

  [http.middlewares.chain-basic-auth]
    [http.middlewares.chain-basic-auth.chain]
      
      middlewares = [ "middlewares-rate-limit", "middlewares-secure-headers", "middlewares-basic-auth"]

What this code block does is that it creates two chains:

  1. chain-no-auth: This specifies the chain to use for services that we do not want to have an authentication layer in front (eg. Plex as it can interfere with Plex access on client devices). For these, we are only specifying the middlewares-rate-limit et middlewares-secure-headers middlewares.
  2. chain-basic-auth: For services that will use basic authentication in front of the service, we are specifying middlewares-basic-auth in addition to the other two.

With these two middleware chains defined, now we can modify the middlewares label in Traefik 2 docker compose as follows:

            - "[email protected]le" 

As evident, middleware chains further simplify the docker-compose files. You can call these chains on any container and they will use the same middleware configuration.

Google OAuth 2.0

By using external middlewares and chains we can simplify our configuration, avoid errors, and also makes our config much easier to update. We can reuse our security headers to improve data transmission security, and basic auth has helped us to restrict access to our service.

There are two problems I have with basic auth though – 1) basic auth is only a single form of authentication, and 2) I have to sign-in each time in order to use my protected services. This can be pretty cumbersome after a while.

But there are other authentication systems that provide even more security (eg. 2-Factor Authentication) and convenience. Good examples are, Google OAuth 2.0, Authelia, and Keycloak.

In this article, we are going to add Google OAuth 2.0 for authenticating access to our services.

Remarque: If you do not need Google OAuth 2.0 authentication, you can skip this section and go to adding additional services.

By implementing Google’s OAuth 2.0 we can solve both of the concerns listed above. Implementing Google’s OAuth 2.0 is free and pretty straight-forward, with only a few small changes to adapt it for Traefik v2.

One thing to note about using Google’s OAuth service with your security headers. If the service is behind OAuth and you’re trying to check whether your security headers are applied, you will probably receive a lower rating. This caused me a lot of concern at first, until realizing that the headers I was seeing were not actually for my service, but for Google’s.

Security Headers with Google OAuth

Security Headers with Google OAuth

Setting up the requirements for OAuth has already been discussed in our other post on Traefik Google OAuth 2.0. Please follow Steps 1 to 2 described there and come back to this post to continue.

Create OAuth Middleware and Chain

Let us now specify a middleware for OAuth. Ouvert middlewares.toml file and add the following lines below what is already present:

  [http.middlewares.middlewares-oauth]
    [http.middlewares.middlewares-oauth.forwardAuth]
      
      address = "http://oauth:4181" # Make sure you have the OAuth service in docker-compose.yml
      trustForwardHeader = true
      authResponseHeaders = ["X-Forwarded-User"]

In addition, let us create a new middleware chain for services that will use Google OAuth. Ouvert middleware-chains.toml and add the following lines below what is already present:

  [http.middlewares.chain-oauth]
    [http.middlewares.chain-oauth.chain]
      
      middlewares = [ "middlewares-rate-limit", "middlewares-secure-headers", "middlewares-oauth"]

Next, let us setup the OAuth Forwarder container.

Setting Up OAuth Forwarder Container

Open your docker-compose-t2.yml file and add the service for OAuth right below the traefik service we created previously.

# Google OAuth - Single Sign On using OAuth 2.0
  oauth:
    container_name: oauth
    image: thomseddon/traefik-forward-auth:latest
    restart: unless-stopped
    networks:
      - t2_proxy
    security_opt:
      - no-new-privileges:true
    environment:
      - CLIENT_ID=$GOOGLE_CLIENT_ID
      - CLIENT_SECRET=$GOOGLE_CLIENT_SECRET
      - SECRET=$OAUTH_SECRET
      - COOKIE_DOMAIN=$DOMAINNAME
      - INSECURE_COOKIE=false
      - AUTH_HOST=oauth.$DOMAINNAME
      - URL_PATH=/_oauth
      - WHITELIST=$MY_EMAIL
      - LOG_LEVEL=info
      - LOG_FORMAT=text
      - LIFETIME=2592000 # 30 days
    labels:
      - "traefik.enable=true"
      ## HTTP Routers
      - "traefik.http.routers.oauth-rtr.entrypoints=https"
      - "traefik.http.routers.oauth-rtr.rule=Host(`oauth.$DOMAINNAME`)"
      - "traefik.http.routers.oauth-rtr.tls=true"
      ## HTTP Services
      - "traefik.http.routers.oauth-rtr.service=oauth-svc"
      - "traefik.http.services.oauth-svc.loadbalancer.server.port=4181"
      ## Middlewares
      - "[email protected]"

Notice that we are using the OAuth middleware chain (chain-oauth) here for authentication instead of basic auth. Before starting the OAuth service, ensure that you have added the following environmental variables to your .env fichier:

  • GOOGLE_CLIENT_ID et GOOGLE_CLIENT_SECRET: Obtained by following our Traefik Google OAuth 2.0 guide.
  • OAUTH_SECRET: This is used to sign the cookie and should be random. Generate a random secret with:
    openssl rand -hex 16
    

    Alternatively, you may use an online service like this one, to generate your random secret.

    Random OAuth Secret

  • MY_EMAIL: Google email id which will be used to authenticate.
  • URL_PATH: This is the same path as the Authorized redirect URI (https://oauth.example.com/_oauth) as explained in our Traefik Google OAuth 2.0 guide.

If you want more than one email id to be able to authenticate and reach your services, use different variables (eg. MY_EMAIL2, MY_EMAIL3, etc.) and list them all separated by commas for WHITELIST:

            - WHITELIST=$MY_EMAIL,$MY_EMAIL2,$MY_EMAIL3

You may also change the duration (LIFETIME) for which the authentication is valid from 30 days specified in seconds to another duration.

Remarque: If you need to logout, signout from your google services in any other tab/window and your OAuth for services will be invalidated.

Once done, use the docker-compose up command listed above or the shortcut dcup2 if you have bash_aliases setup. You should now be redirected to Google OAuth login page before reaching the service.

Google OAuth Login for Docker Services

Google OAuth Login for Docker Services

Reconfigure Traefik 2 Dashboard to use OAuth

At this point, our Traefik reverse proxy dashboard is setup to use basic authentication. Let us now change it to use Google OAuth. This is now as simple as changing chain-basic-auth à chain-oauth in the docker-compose file (shown below).

            - "[email protected]" 

So there you go, Docker Traefik 2 setup with Google OAuth 2.

Once done, use the docker-compose up command listed above or the shortcut dcup2 if you have bash_aliases setup.

Adding Apps to Traefik 2 Docker Home Server Stack

Now that our Traefik 2 and OAuth are up and running, let us start adding some apps. Earlier, I listed examples of some of the apps that I wanted my Traefik 2 Docker server to run.

We are not going to show you how to install all of these apps using docker and put them behind Traefik 2 reverse proxy. Instead, we will show you a few apps that highlight a specific kind of configuration.

Once you read and understand this guide, it should be quite simple to use the docker-compose snippets from our GitHub Repos to set up the other apps that you are interested in (Anand's Repo and Seth's Repo).

Portainer with Traefik 2 and OAuth

We have covered Portainer installation previously. Portainer provides a WebUI to manage all your docker containers. I strongly recommend this for newbies. Here is the code to add (copy-paste) in the docker-compose file (pay attention to blank spaces at the beginning of each line):

# Portainer - WebUI for Containers
  portainer:
    container_name: portainer
    image: portainer/portainer:latest
    restart: unless-stopped
    command: -H unix:///var/run/docker.sock
    networks:
      - t2_proxy
    security_opt:
      - no-new-privileges:true
#    ports:
#      - "$PORTAINER_PORT:9000"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - $USERDIR/docker/portainer/data:/data 
    environment:
      - TZ=$TZ
    labels:
      - "traefik.enable=true"
      ## HTTP Routers
      - "traefik.http.routers.portainer-rtr.entrypoints=https"
      - "traefik.http.routers.portainer-rtr.rule=Host(`portainer.$DOMAINNAME`)"
      - "traefik.http.routers.portainer-rtr.tls=true"
      ## Middlewares
#      - "[email protected]e" # No Authentication
#      - "[email protected]file" # Basic Authentication
      - "[email protected]" # Google OAuth 2.0
      ## HTTP Services
      - "traefik.http.routers.portainer-rtr.service=portainer-svc"
      - "traefik.http.services.portainer-svc.loadbalancer.server.port=9000"

Configure:

  1. PORTAINER_PORT: Port number on which you want the portainer WebUI to be available at. It could be the same port as the container: 9000 (must be free). Ensemble PORTAINER_PORT in your .env fichier. Specifying ports is optional since we are using reverse proxy and can reach portainer at portainer.example.com.
  2. Authentication: Only OAuth middleware chain is enabled. If you want basic authentication or no authentication, uncomment the corresponding line and comment out the other middlewares.

Once done, use the docker-compose up command listed above or the shortcut dcup2 if you have bash_aliases setup.

Portainer WebUI should be available at https://portainer.example.com.

Portainer with Traefik 2 LetsEncrypt Wildcard SSL Certificate

Portainer with Traefik 2 LetsEncrypt Wildcard SSL Certificate

Traefik 2 seems to be using the correct SSL certificates.

Organizr – Unified HTPC/Home Server Web Interface

A Docker home server with several apps may be cool but now you will have to remember all the different port numbers to access them. That is where Organizr comes in. Organizr provides a unified interface to access all your home server apps so you do not have to remember them individually.

In essence, Organizr is similar to HTPC Manager or Muximux.

Here is the code to add in the docker-compose file (pay attention to blank spaces at the beginning of each line):

# Organizr - Unified Frontend
  organizr:
    container_name: organizr
    image: organizrtools/organizr-v2:latest
    restart: unless-stopped
    networks:
      - t2_proxy
    security_opt:
      - no-new-privileges:true
#    ports:
#      - "$ORGANIZR_PORT:80"
    volumes:
      - $USERDIR/docker/organizr:/config
    environment:
      - PUID=$PUID
      - PGID=$PGID
      - TZ=$TZ
    labels:
      - "traefik.enable=true"
      ## HTTP Routers
      - "traefik.http.routers.organizr-rtr.entrypoints=https"
      - "traefik.http.routers.organizr-rtr.rule=Host(`$DOMAINNAME`,`www.$DOMAINNAME`)" 
      - "traefik.http.routers.organizr-rtr.tls=true"
      ## Middlewares
      - "[email protected]"
      ## HTTP Services
      - "traefik.http.routers.organizr-rtr.service=organizr-svc"
      - "traefik.http.services.organizr-svc.loadbalancer.server.port=80"

As explained for Portainer (above), enable and customize the ports et environnement sections as needed. Add any missing environmental variables to .env. Save and update your stack (shortcut dcup2 with my bash_aliases example).

Why did I include Organizr as an Example?

Notice the following line:

            - "traefik.http.routers.organizr-rtr.rule=Host(`$DOMAINNAME`,`www.$DOMAINNAME`)" 

We are setting up Organizr to be served on my root domain (example.com or www.example.com). So that will be the face of my domain. From there, we have links to all my apps.

Remarque: I found that adding a lot of apps to Organizr slowed it down.

I only have 4 essential apps as tabs and a 5th tab for Heimdall. Heimdall is similar to Organizr and shows the links to rest of my apps. You can find Heimdall docker-compose snippet in my GitHub Repo.

Recommended Media Center Companion Apps:

MariaDB – MySQL Database

In my original Docker server guide, many people wanted MariaDB, which is one of the most commonly used database servers. In my case, Home Assistant (Hass.io), Guacamole, StatPing, and ZoneMinder are all writing data to MariaDB databases.

Here is the code to add in the docker-compose file (pay attention to blank spaces at the beginning of each line):

# MariaDB - MySQL Database
  mariadb:
    container_name: mariadb
    image: linuxserver/mariadb:latest
    restart: always
    networks:
      t2_proxy:
        ipv4_address: 192.168.90.250 
    security_opt:
      - no-new-privileges:true
    ports:
      - "3306:3306"
    volumes:
      - $USERDIR/docker/mariadb/data:/config
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    environment:
      - PUID=$PUID
      - PGID=$PGID
      - MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD

As explained for Portainer (above), enable and customize the environnement section as needed. Add any missing environmental variables to .env. Save and update your stack (shortcut dcup2 with my bash_aliases example).

Why did I include MariaDB as an Example?

Notice that we are specifying a static IP to MariaDB container (192.168.90.250), just as I did for Traefik 2 Dashboard.

In addition, we are mapping port 3306 of the container to port 3306 of the host. I can reach MariaDB through HOST-IP:3306 or 192.168.90.250:3306. Of course, this is redundant and I can disable the ports section (and only use 192.168.90.250:3306) or not assign a static IP to MariaDB container.

Guacamole – HTML 5 based Remote desktop, SSH, on Telnet Gateway

Apache Guacamole is a clientless remote desktop gateway. It supports standard protocols like VNC, RDP, and SSH. It needs no plugins or software and works from any modern browser. In my opinion, it is a must-have for admins.[[Lis: Setup VNC Server on Ubuntu: Complete Ubuntu Remote Desktop Guide]

It is not easy to setup Guacamole as an app on host systems. But docker has made this very easy. In addition, OAuth provides much-needed security (since a security breach will expose all your remote connections).

Here is the code to add in the docker-compose file (pay attention to blank spaces at the beginning of each line):

# Guacamole - Remote desktop, SSH, on Telnet on any HTML5 Browser 
  guacamole:
    image: guacamole/guacamole:latest
    container_name: guacamole
    restart: unless-stopped
    networks:
      - t2_proxy
    security_opt:
      - no-new-privileges:true
#    ports:
#      - "$GUACAMOLE_PORT:8080"
    environment:
      GUACD_HOSTNAME: guacd
      MYSQL_HOSTNAME: $DB_HOST
      MYSQL_PORT: $DB_PORT
      MYSQL_DATABASE: guacamole
      MYSQL_USER: $GUAC_MYSQL_USER
      MYSQL_PASSWORD: $GUAC_MYSQL_PASSWORD
    labels:
      - "traefik.enable=true"
      ## HTTP Routers
      - "traefik.http.routers.guacamole-rtr.entrypoints=https"
      - "traefik.http.routers.guacamole-rtr.rule=Host(`guac.$DOMAINNAME`)"
      - "traefik.http.routers.guacamole-rtr.tls=true"
      ## Middlewares
      - "[email protected],add-guacamole" 
      - "traefik.http.middlewares.add-guacamole.addPrefix.prefix=/guacamole"
      ## HTTP Services
      - "traefik.http.routers.guacamole-rtr.service=guacamole-svc"
      - "traefik.http.services.guacamole-svc.loadbalancer.server.port=8080"

As explained for Portainer (above), enable and customize the ports et environnement sections as needed. Add any missing environmental variables to .env. Save and update your stack (shortcut dcup2 with my bash_aliases example).

Note that Guacamole requires that a database be setup and initialized before it can work. We will cover this in a separate post.

Why did I include Guacamole as an Example?

Notice that we have a links section. Guacamole needs Guacamole Daemon (guacd) to be up and running as well. This runs as a separate container (see my GitHub repo for Docker Compose snippet). If guacd container is not up, Guacamole will not start or throw an error.

The main reason I include Guacamole as an example is to showcase the addPrefix.prefix middleware. If I visit guac.example.com, it will take me to the page shown below, which is a generic page with some information and not the Guacamole login page I want to reach.

Guacamole without addPrefix Traefik Middleware

Guacamole without addPrefix Traefik Middleware

The login page is available at guac.example.com/guacamole. Instead of typing /guacamole manually I can define as addPrefix.prefix middleware:

            - "traefik.http.middlewares.add-guacamole.addPrefix.prefix=/guacamole"

Then you can activate this middleware by adding add-guacamole à la middlewares label as shown in the Guacamole docker-compose example above. This causes guac.example.com/guacamole to be served through guac.example.com.

Another app that benefits from the addPrefix.prefix middleware is PiHole (described later). However, it does not work for all apps. For example, this does not work for ZoneMinder, which needs /zm/ prefix.

qBittorrent – Torrent downloader

qBittorrent is one of my favorite cross-platform BitTorrent clients. I use Transmission Bittorrent with IPVanish VPN. But there is a reason I included qBittorrent as an example.

Here is the code to add in the docker-compose file (pay attention to blank spaces at the beginning of each line):

# qBittorrent - Torrent downloader
  qbittorrent:
    image: linuxserver/qbittorrent:latest
    container_name: qbittorrent
    restart: always
    network_mode: container:transmission-vpn
    security_opt:
      - no-new-privileges:true
    volumes:
      - $USERDIR/docker/qbittorrent:/config
      - $USERDIR/Downloads:/downloads
    environment:
      PUID: $PUID
      PGID: $PGID
      TZ: $TZ
      UMASK_SET: 002
      WEBUI_PORT: 8168
    labels:
      - "traefik.enable=true"
      ## HTTP Routers
      - "traefik.http.routers.qbittorrent-rtr.entrypoints=https"
      - "traefik.http.routers.qbittorrent-rtr.rule=Host(`qbit.$DOMAINNAME`)"
      - "traefik.http.routers.qbittorrent-rtr.tls=true"
      ## Middlewares
      - "[email protected]e"
      ## HTTP Services
      - "traefik.http.routers.qbittorrent-rtr.service=qbittorrent-svc"
      - "traefik.http.services.qbittorrent-svc.loadbalancer.server.port=8168"

As explained for Portainer (above), enable and customize the ports et environnement sections as needed. Add any missing environmental variables to .env. Save and update your stack (shortcut dcup2 with my bash_aliases example).

Note that the default qBittorrent port is 8080. I use a different port (8168) and this is specified in my qBittorrent settings. Most likely you will have to change 8168 to 8080 (2 instances).

Why did I include qBittorrent as an Example?

As I said before, we have set up Transmission with IPVanish VPN. If VPN is not connected Transmission will stop. See my GitHub repo for Transmission with VPN Docker Compose snippet.

IPVanish VPN Exclusive Offer – only $3.25 per month:

VPN Guides
Windows, Android, Ubuntu
Kodi OpenVPN
OSMC on RPi

♦ Hide your browsing (no logs), Anonymize Streaming and Downloads
♦ Circumvent Geo/Country Restrictions and access worldwide content
♦ Works on Windows, Mac, Linux, Android, iOS, Router, and more
♦ 250 GB of SugarSync Secure storage included
♦ Money back guarantee – S'inscrire maintenant

We are using the existing VPN connection on the transmission container to put qBittorrent also behind VPN by defining qBittorrent's network as below:

        network_mode: container:transmission-vpn

transmission-vpn is the name of my transmission container. With this method, you can put any container on the same network as another container. Note that if both containers expose the same ports, there could be conflicts and you may have to customize the ports. However, this is not a problem for Transmission and qBittorrent.

NextCloud – Your Own Cloud Storage

NextCloud (like OwnCloud) offers your own cloud storage to manage files and documents (like Google Drive/Docs).

You can find an example docker-compose for NextCloud on Seth's GitHub Repo.

Why did I include NextCloud as an Example?

If you choose to not enable the –serversTransport.insecureSkipVerify=true CLI argument (comment it out) you will need a slightly different setup. Nextcloud’s WebUI is only accessible using an HTTPS port, and while Traefik communicates externally to clients using the LetsEncrypt cert, it communicates to services on the back-end using HTTP.

In the past, I needed to use the InsecureSkipVerify option, but we want to keep our reverse proxy secure, so let’s find another way.

All of the configurations that we’ve worked with so far have been for Traefik’s ‘HTTP’ routers, but Traefik v2 also offers the option to configure TCP routers. Traefik’s TCP service has a pass-through option which will allow us to "pass-through" our secure connection to Nextcloud. The labels that we will need to use are:

#### SEE GITHUB LINKED ABOVE FOR REST OF THE DOCKER-COMPOSE
      ## TCP Routers
      - "traefik.tcp.routers.nextcloud-tcp.entrypoints=https"
      - "traefik.tcp.routers.nextcloud-tcp.rule=HostSNI(`nextcloud.$DOMAINNAME`)"
      - "traefik.tcp.routers.nextcloud-tcp.tls=true"
#      - "traefik.tcp.routers.nextcloud-tcp.tls.certresolver=dns-cloudflare"
      - "traefik.tcp.routers.nextcloud-tcp.tls.passthrough=true"
      ## TCP Services
      - "traefik.tcp.routers.nextcloud-tcp.service=nextcloud-tcp-svc"
      - "traefik.tcp.services.nextcloud-tcp-svc.loadbalancer.server.port=443"

Here you can see that we need to use the rule HostSNI on TCP routers to designate which incoming address Traefik should listen for.

The reason I’ve enabled TCP for only one of my services is that you cannot add middleware to TCP routes. This means, primarily, that you cannot add basic-auth or OAuth to these typically very sensitive interfaces.

Autres applications

There are several more apps in our Docker Traefik 2 server setup. The above examples show most of the possibilities.

For docker-compose examples for over 50 apps, check our current GitHub Repos (Anand's Repo and Seth's Repo). These repos includes apps such as Radarr, Sonarr, Lidarr, SABnzbd, and more.

Usenet is Better Than Torrents:

For apps like Sonarr, Radarr, SickRage, and CouchPotato, Usenet is better than Torrents. Unlimited plans from Newshosting (US Servers), Eweka (EU Servers), or UsenetServer, which offer >3000 days retention, SSL for privacy, and VPN for anonymity, are better for HD content.

Adding non-docker or external apps behind Traefik

We have Traefik v2 working well for all of our services within our Docker network, but what about connecting to other hosts outside of Docker? We have a few of those (eg. Home Assistant, PiHole). Traefik can also reverse proxy them and it is easy to implement.

Traefik’s File provider allows us to add dynamic routers, middlewares, and services. Earlier we only used our rules directory to add middlewares, but we can easily add an external host by adding a new file to this directory. Traefik will auto-detect and update its configurations.

For this example, we will create a new route to an external PiHole running on a Raspberry Pi. Let us create a file called app-pihole.toml dans le rules folder and add the following content to it.

[http.routers]
  [http.routers.pihole-rtr]
      
      entryPoints = ["https"]
      rule = "Host(`pihole.example.com`)"
      service = "pihole-svc"
      middlewares = ["chain-oauth", "pihole-add-admin"]
      [http.routers.pihole-rtr.tls]
        
        certresolver = "dns-cloudflare"

[http.middlewares]
  [http.middlewares.pihole-add-admin.addPrefix]
    
    prefix = "/admin"

[http.services]
  [http.services.pihole-svc]
    [http.services.pihole-svc.loadBalancer]
      
      passHostHeader = true
      [[http.services.pihole-svc.loadBalancer.servers]]url = "http://192.168.1.26:80" # or whatever your external host's IP:port is

As you can see there are three sections: routers, middlewares, and services. PiHole frontend will be available at pihole.example.com. The service (backend) will be available at 192.168.1.26:80, which is the IP address of the Raspberry Pi that runs PiHole.

In addition, we also have a middleware pihole-add-admin. This middleware is the add-prefix middleware that I explained previously for Guacamole. It will automatically add the ending /admin à pihole.example.com and take us directly to the admin page, instead of the one below.

PiHole without addPrefix Traefik Middleware

PiHole without addPrefix Traefik Middleware

Since our rules directory is dynamic, simply by adding this file to that directory we have created the route. If you’ve added an external host you should be able to connect to your service now, without restarting Traefik!

Troubleshooting Apps

Here are some issues either I ran into or others have mentioned.

Traefik 2 Not Pulling SSL Certificates

One of the most common reasons for this is that DNS changes have not propagated yet. Depending on the registrar, this can take several minutes.

If your staging was successful and fetching real certificates fail, wait a few more minutes and try again.

If after that Traefik 2 continues to fail to fetch certificates for some of the services, try adding the following label to each of the services.

            - "traefik.http.routers.jdownloader-rtr.tls.certresolver=dns-cloudflare"

Remember that we added this certresolver router to our Traefik 2 service and commented it out once wildcard certificates were pulled. We did not add this to any other service. Adding this seems to resolve the problem for some.

The downside to adding the certresolver router label to each of the services may be that Traefik reverse proxy will fetch separate certificates for each of the services instead of using the wildcard certificate.

Typos and Misnaming

Typos and misnaming are two of the most common mistakes people do. For example, when I was creating Portainer, I had a typo in a middleware name. This caused Portainer to not start.

Checking Traefik 2 logs can help you figure out what the problem is. In addition, check Traefik 2 dashboard for more information (see below).

Traefik v2 Router Error on Dashboard

Traefik v2 Router Error on Dashboard

In the case of Portainer, upon digging deeper, Traefik 2 dashboard revealed that Traefik 2 could not find the middlewares.chain-no-auth.

Traefik 2.0 Router Error Details

Traefik 2.0 Router Error Details

This should have been middlewares-chain-no-auth (- instead of .). Once I fixed this issue, Portainer started right up.

Tools to Check Logs

Recently, one of my GitHub followers recommended Dozzle. I quickly became a big fan of it. Dozzle allows you to monitor logs of all your docker containers in real-time. This helps to troubleshoot and fix issues.

Following logs with Dozzle

Following logs with Dozzle

You can find the docker-compose example for Dozzle in my GitHub Repo.

Docker Traefik 2 Home Server – Final Thoughts

In this guide, I combined three of my previous (Docker media server, Traefik 1, and Google OAuth) guides into one. As you can see it turned out to be a lengthy one. But it provides a one-stop solution for implementing Traefik 2 reverse proxy for Docker services.

As mentioned before, one of the main advantages of a reverse proxy is the ability to expose the app to the internet without exposing their ports. If you have successfully implemented reverse proxy for docker then at this point I strongly recommend disabling port forwards on your router (except 80 and 443 that Traefik needs). You would still be able to access your apps using IP-ADDRESS:port from your home network.

Traefik 2 may look drastically different from Traefik 1. But in reality, they are more similar than not. Hopefully, this guide broke things down enough for you to understand the concepts.

This post was co-authored by Seth, without whose help it would have been tough for me to migrate from Traefik 1 to 2. We are by no means "experts" on this topic. So if you have a better way of doing what we did, please feel free to share in the comments and we will respond and update the guide if needed.

Otherwise, we hope that this Traefik 2 Docker Home Server setup tutorial guide helped you accomplish what you set out to do.

IPVanish VPN Exclusive Offer – only $3.25 per month:

VPN Guides
Windows, Android, Ubuntu
Kodi OpenVPN
OSMC on RPi

♦ Hide your browsing (no logs), Anonymize Streaming and Downloads
♦ Circumvent Geo/Country Restrictions and access worldwide content
♦ Works on Windows, Mac, Linux, Android, iOS, Router, and more
♦ 250 GB of SugarSync Secure storage included
♦ Money back guarantee – S'inscrire maintenant

We Are Hiring: Familiar with Smart Home Automation, Media Streaming, HTPC, and Home Server topics? Tinkerers and hobbyists preferred. Writing experience optional. APPLY HERE.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.