HOWTO

Je suis les instructions ici : https://hub.docker.com/r/jwilder/nginx-proxy

Le principe

  • Problème : On veut lancer des sites web variés mais on ne veut pas configurer Nginx.
  • Solution : On se dit qu’on va lancer chaque site dans son conteneur Docker.
  • Problème : on n’a qu’un seul port 80 à disposition. Vers quel conteneur va-t-on rediriger les requêtes ?
  • Solution : on va mettre en place des vhosts,…
  • Problème : zut, il faut alors quand même configurer un nginx sur la machine hôte ?!
  • Solution : Eh non ! On va conteneuriser (?) ce nginx ! Et en plus… c’est déjà fait ! Il s’appelle nginx-proxy

Bref on va lancer un conteneur nginx frontal qui va dispatcher les requêtes vers le bon conteneur en fonction d’un vhost. Voir le joli schéma ici : https://dimuthukasunwp.github.io/Articles/Hosting-multiple-sites-or-applications-using-Docker-and-NGINX-reverse-proxy-with-Letsencrypt-SSL.html

Première étape : lancer le nginx “frontal”

Lancer sur le serveur (dans mon cas, un VPS OVH avec Docker-sur-Debian10 pré-installé) :

docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy

Ceci indique simplement de :

  • exécuter l’image jwilder/nginx-proxy (qui sera rapatriée du Docker Hub),
  • exposer le port 80 sur le port 80, et
  • monter /var/run/docker.sock (sur la machine hôte) sur /tmp/docker.sock (dans le conteneur docker) pour que le conteneur puisse avoir toute l’info sur les autres conteneurs qui seront lancés.

Seconde étape : configurer le DNS

A priori on aimerait que le domaine mon.domaine.top résolve vers l’IP de la machine.

Pour mon tests, j’ai simplement ajouté une ligne contenant ip-de-mon-serveur mon.domaine.top dans mon /etc/hosts (sur ma machine client). De la sorte, pas besoin de configurer un vrai nom de domaine juste pour tester.

À partir de ceci, on doit avoir une erreur 503 en se connectant à http://mon.domaine.top/. C’est normal, nginx ne sait pas encore où rediriger les requêtes.

Troisième étape : lancer un serveur

Pour les besoins de tests, je vais juste lancer un netcat en mode écoute (nc -l) sur le serveur :

docker run --expose 1234 -e VIRTUAL_HOST=mon.domaine.top -it --rm alpine:latest nc -l -p 1234

à partir de là, je retente la connexion depuis mon client vers http://mon.domaine.top/ et les entêtes apparaissent côté serveur :

GET / HTTP/1.1
Host: mon.domaine.top
Connection: close
X-Real-IP: ip-de-mon-serveur
X-Forwarded-For: ip-de-mon-serveur
X-Forwarded-Proto: http
X-Forwarded-Ssl: off
X-Forwarded-Port: 80
X-Original-URI: /
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: fr-BE,fr;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Upgrade-Insecure-Requests: 1
Sec-GPC: 1

Je peux même répondre (sur le serveur), par exemple en tapant “bazinga” suivi de RET puis ^D. Mon navigateur montre alors “bazinga”.

Conclusion

C’est cool, ça marche. Il n’y a plus qu’à lancer des conteneurs qui exposent un port tout en leur définissant un VIRTUAL_HOST, et boum ça marche !