Dans la majorité des cas, on utilise Docker pour installer un service et partager les ports de ce service avec celui de la machine.

version: "3"
web:
  image: nginx
  volumes:
    - ./templates:/etc/nginx/templates
  ports:
    - "8080:80"
  environment:
    - NGINX_HOST=foobar.com
    - NGINX_PORT=80

Ici, dans le docker-compose.yml d’exemple pour un serveur nginx, on distribue le port 80 du conteneur nginx sur le port 8080 de la machine hôte.

Il peut arriver d’avoir besoin de la situation inverse, accéder à un service de la machine via un port depuis le conteneur. Comme par exemple : partager un service de la machine via un serveur web conteneurisé.


Avec docker, il est possible d’utiliser l’option add_host (ou extra_host pour docker-compose) pour paramétrer les hosts du conteneur. Comme dans l’exemple qui suit (documentation):

extra_hosts:
  - "somehost:162.242.195.82"
  - "otherhost:50.31.209.229"

L’adresse IP attribuée à votre machine étant modifiée régulièrement, Docker Windows et macOS donne la possible d’utiliser le host host.docker.internal directement pour faire référence à l’IP de votre machine. En voici un exemple (documentation) :

 $ docker run --rm -it alpine sh
 $ apk add curl
 $ curl http://host.docker.internal:8000
 $ exit

Depuis Docker 20.10, un paramètre à utiliser avec addhost (ou _extra_hosts si docker-compose) été ajouté dans Docker pour Linux.

version: "3"
services:
  proxy:
    image: nginx
    volumes:
      - ./templates:/etc/nginx/templates
    restart: unless-stopped
    networks:
      - default
    extra_hosts:
      - "host.docker.internal:host-gateway"

Ce qui vous permet de faire appel à un service de la machine hôte.

Pour tester facilement si ça marche sur votre machine, créez un docker-compose.yml avec cette configuration :

version: "3"

services:
  pingtest:
    image: alpine
    extra_hosts:
      - "host.docker.internal:host-gateway"

Puis faites cette commande :

docker-compose run –rm pingtest ping host.docker.internal

Vous devriez obtenir un résultat comme celui-ci :

Creating test_pingtest_run ... done
PING host.docker.internal (172.17.0.1): 56 data bytes
64 bytes from 172.17.0.1: seq=0 ttl=64 time=0.525 ms
64 bytes from 172.17.0.1: seq=1 ttl=64 time=0.311 ms
64 bytes from 172.17.0.1: seq=2 ttl=64 time=0.302 ms
64 bytes from 172.17.0.1: seq=3 ttl=64 time=0.220 ms
64 bytes from 172.17.0.1: seq=4 ttl=64 time=0.253 ms
64 bytes from 172.17.0.1: seq=5 ttl=64 time=0.331 ms
^C
--- host.docker.internal ping statistics ---
6 packets transmitted, 6 packets received, 0% packet loss
round-trip min/avg/max = 0.220/0.323/0.525 ms

Le hostname de votre machine hôte est appelé host.docker.internal pour rester cohérent avec macOS et Windows.


Voilà dès à présent vous pouvez utiliser les ports de la machine hôte dans vos conteneurs Docker. Attention néanmoins, cela brise un peu le concept d’encapsulation des containeurs Docker et de sécurité, en laissant le conteneur accéder aux services réseaux de la machine.

À utiliser avec parcimonie et réflexion !


Rapport à Docker 🐳
Rapport à Docker 🐳

Nous espérons que vous avez trouvé cet article intéressant et qu’il a pu vous aider. N’hésitez pas à faire vos retours sur le compte Twitter de KBDev.

Mis à jour :