DockerSystème

Docker, Nginx et les certificats SSL

Prérequis : Avoir installé et configuré correctement Docker – Posséder un nom de domaine valable

Pour votre déploiement d’infrastructure, vous aurez sûrement besoin de définir un nom de domaine et des certificats SSL pour l’accès et la sécurité sur votre système. Pour cela, nous allons utiliser un système de proxy Nginx couplé à Let’s Encrypt, pour la génération automatique de certificats SSL.

Attention : Let’s Encrypt ne permet de générer que 10 certificats par domaine tous les 7 jours. Si vous essayez d’en générer plus, le système échouera et la plupart des navigateurs récents ne vous laisserons pas accéder au système.

Création du docker-compose

Pour pouvoir utiliser ce système sur n’importe quelle machine rapidement, il faut créer un fichier docker-compose que Docker pourra exécuter pour mettre en place et faire fonctionner les machines.

Voici un exemple pour Nginx et Let’s Encrypt :

# Nginx
nginx-reverse-proxy:
    image: jwilder/nginx-proxy
    container_name: nginx-reverse-proxy
    restart: always
    ports:
        - "80:80"
        - "443:443"
    volumes:
        - /docker/ssl:/etc/nginx/certs:ro
        - /var/run/docker.sock:/tmp/docker.sock:ro
        - /docker/nginx/conf.d:/etc/nginx/conf.d
        - /etc/nginx/vhost.d
        - /usr/share/nginx/html
    labels:
        - com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy

# Let's Encrypt
letsencrypt-nginx-proxy-companion:
    image: jrcs/letsencrypt-nginx-proxy-companion
    restart: always
    volumes_from:
        - nginx-reverse-proxy
    container_name: letsencrypt
    volumes:
        - /docker/ssl:/etc/nginx/certs:rw
        - /var/run/docker.sock:/var/run/docker.sock:ro

Lancez ensuite la commande docker-compose up -d pour lancer l’installation des deux conteneurs.

Dans cet exemple, nous pouvons voir que tous les volumes sont mappés sur la machine (chemin absolu situé à gauche dans les sections « volumes ») et notamment celui des certificats SSL partagé sur les deux conteneurs. Seul Nginx possède des ports à ouvrir, qui sont le 80 pour le protocole HTTP et 443 pour le protocole HTTPS.

A présent que les deux conteneurs sont en marche, nous allons tester le bon fonctionnement en ajoutant (ou en modifiant) une 3ème machine qui nécessite de se connecter à une interface web : Portainer. Cette machine est un peu particulière car elle utilise un port non standard pour y accéder.

portainer:
    image: portainer/portainer
    restart: always
    container_name: portainer
    command: -H unix:///var/run/docker.sock
    volumes:
        - /var/run/docker.sock:/var/run/docker.sock
        - /server/portainer/portainer_data:/data
    environment:
        - LETSENCRYPT_HOST=supervision.votre_domaine.com
        - LETSENCRYPT_EMAIL=votre_email@votre_domaine.com
        - VIRTUAL_HOST=supervision.votre_domaine.com
        - VIRTUAL_PORT=9000
    hostname: supervision.votre_domaine.com

Les champs LETSENCRYPT_HOST et LETSENCRYPT_EMAIL sont obligatoires pour la génération de certificats. Les champs VIRTUAL_HOST et hostname quant à eux, sont nécessaires au bon fonctionnement de notre proxy Nginx. Enfin, le virtual port est utilisé pour rediriger le port 9000 non-standard vers les ports 443 et 80.

N’oubliez pas de déclarer votre nouveau sous domaine dans votre zone DNS.

Pour aller plus vite, exécutez les commandes suivante pour redémarrer les machines existantes et installer (ou réinstaller) Portainer :

docker-compose down
docker-compose up -d

Accédez ensuite à l’adresse que vous avez défini (https://supervision.votre_domaine.com) et vous allez tomber sur votre nouveau système de supervision déployé et sécurisé par un certificat SSL signé.

4 Comments
  • Christophe
    4:16 , 19 octobre 2018

    Merci !!! Bon j’arrive pas dans tous les cas à faire marcher portainer arrff j’ai comme erreur :

    sudo docker-compose up
    ERROR: yaml.parser.ParserError: while parsing a block mapping
    in « ./docker-compose.yml », line 1, column 1
    expected , but found  »
    in « ./docker-compose.yml », line 3, column 3

    • Quentin Laurent
      7:23 , 31 octobre 2018

      Cela ressemble à un problème avec l’indentation du fichier docker-compose. Avez-vous vérifié que ce ne sont que des espaces dans votre fichier, et non des tabulations ? Yml a du mal avec ça…

  • David
    11:52 , 16 juillet 2019

    Super tuto. Bien plus clair que la moyenne. J’essaye de transposer ce docker compose sur un de mes projets et me retrouve avec une bad gateway 502. Avec une Nginx standard, je reprendrais le nginx.conf mais j’ai l’impression que jwilder/nginx-proxy fonctionne sur une logique différente. Tout a l’air de dépendre de hostname: supervision.votre_domaine.com mais je ne suis pas sur de bien comprendre sa fonction et docker-compose (v 3.7) me balance un « In file ‘./docker-compose.prod.yml’, service ‘hostname’ must be a mapping not a string. »

    • Quentin Laurent
      12:46 , 16 juillet 2019

      Merci David pour votre retour ! Pour clarifier un peu, le champ « hostname » permet à Docker de savoir à quelle machine s’adresser. On peut l’apparenter au fichier « hosts » d’une machine Linux, attribuant des adresses IP à des noms de domaines particulier. Pour l’erreur que renvoie docker-compose, c’est parce que le terme « hostname » doit être indenté au même niveau que les champs « images » ou « volumes ». C’est une erreur qui s’est glissée dans l’article et que je viens de corriger.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *