Dans cet article, je vous propose de mettre en place un serveur web NGINX qui va servir de frontal pour vos différents conteneurs Docker.
La solution retenu permet de configurer automatiquement NGINX à partir des images et containers démarrés par Docker sans opération manuelle de votre part sur Nginx. Nous utilisons l’outil docker-gen pour la configuration de nginx. Un deuxième article sera bientôt disponible pour activer https et vous aider à gérer les certificats automatiquement avec Let’s Encrypt
docker-gen
Docker Gen est un générateur de fichier qui se base sur les métadonnées obtenus sur les containers lancés sur votre machine. Docker-gen va utiliser les informations liées au container ( docker inspect) pour récupérer les variables d’environnements, les ports exposés et les adresses ip des containers. A partir de ces informations, docker-gen va générer un fichier à partir d’un fichier de template de départ.
Projet Github : https://github.com/jwilder/docker-gen
Dans notre exemple, nous allons utiliser cet utilitaire pour générer le fichier de conf de NGINX, mais il peux s’adapter à de très nombreux besoins:
- Configuration des reverses proxy (Nginx, Apache, HAProxy)
- Gestion des logs
- Service Discovery
- Générateur de documentation
Docker-gen fonctionne soit en ligne de commande, soit sous la forme d’une image Docker.
Voici le fichier docker-compose permettant de lancer nginx et l’image nginx_gen
nginx: image: nginx:1.11 container_name: nginx ports: - "80:80" - "443:443" volumes: - ./generated/nginx/conf.d:/etc/nginx/conf.d - ./generated/nginx/html:/usr/share/nginx/html - ./templates:/etc/docker-gen/templates nginx_gen: image: jwilder/docker-gen container_name: nginx-gen volumes_from: - nginx volumes: - /var/run/docker.sock:/tmp/docker.sock:ro - ./templates:/etc/docker-gen/templates:ro links: - nginx entrypoint: /usr/local/bin/docker-gen -notify-sighup nginx -watch -only-exposed -wait 5s:30s /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
Le container docker-gen va surveiller en permance le lancement et l’extinction des conteneurs sur votre machine. A chaque changement, nginx-gen analysera les variables environnement des containers lancés et générera un nouveau fichier default.conf à partir du fichier de template nginx.tmpl.
Une fois le fichier de configuration généré, le entrypoint indique qu’il au container qu’il doit faire une notification à NGINX pour recharger à chaud sa configuration.
Pour information, il existe aussi une image /nginx-proxy qui hérite de Nginx et intègre automatiquement docker-gen. L’image simplifie la configuration et évite de lancer plusieurs containers. Cela peux répondre à des besoins simples, mais vous ne pourrez pas surcharger le fichier template par défaut. De plus, l’image nécessite de donner accès en lecture seul au socket /var/run/docker.sock à un container qui sert de frontal et qui est exposé sur internet. C’est pour cette raison sécuritaire que je préfère utiliser 2 images distincts
Fichier de template
Voici un exemple de fichier template (la version complète du fichier est fournit dans le repo git)
{{ range $host, $containers := groupByMulti $ "Env.VIRTUAL_HOST" "," }} upstream {{ $host }} { {{ range $index, $value := $containers }} {{ with $address := index $value.Addresses 0 }} # {{$value.Name}} server {{ $network.IP }}:{{ $address.Port }}; {{ end }} {{ end }} } {{ end }}
Et voici l’explication, pour chaque container identifié avec une variable d’environnement « VIRTUAL_HOST », ajouter dans l’instruction nginx upstream la liste des toutes les adresses ip des containers docker.
Voici maintenant comment démarrer votre propre container en y ajoutant la variable d’environnement adaptée
tomcat: image: tomcat:8.0 environment: - VIRTUAL_HOST=tomcat.demo.w3blog.fr
Dans notre exemple, nous générons des sous-domaines, mais si vous connaissez le fonctionnement d’une configuration nginx, vous pourrez très facilement adapter le template pour gérer des sous-répertoires ou n’importe quel configuration plus complexe.
Une fois l’outil docker-gen pris en main, les possibilités offertes par ce simple outil en ligne de commande sont énormes. Pour répondre à une problématique de scalabilité, nous avons utiliser docker-gen pour ajouter automatiquement les adresses ip d’une même image lancé plusieurs fois et ainsi faire du load-balancing avec nginx.
Dans un prochaine article, nous ajouterons à cette exemple une configuration automatique de vos certificats Let’s encrypt.