## Intro

Le réseau Docker détermine comment vos services se découvrent mutuellement et comment les clients les atteignent. Dans ce guide, vous allez :

- Comprendre les réseaux bridge, host et overlay

- Publier des ports en toute sécurité pour que le trafic atteigne le bon conteneur

- Utiliser le DNS entre conteneurs pour que les services communiquent par nom

- Définir des réseaux dans Docker Compose pour des configurations reproductibles

- Dépanner rapidement les problèmes de connectivité

Ce guide s'adresse aux opérateurs pressés qui veulent des étapes pratiques et des exemples copier-coller qui fonctionnent sur de vraies machines.

## Aperçu du flux de travail

Utilisez cette séquence pour choisir et implémenter le bon mode réseau :

- Préciser la portée

- Hôte unique : commencez par un réseau bridge défini par l'utilisateur. Il isole les conteneurs et fournit un DNS intégré entre eux.

- Performance type métal nu sur Linux : envisagez le réseau host. Il supprime le NAT mais expose les ports des conteneurs directement sur la pile réseau de l'hôte.

- Multi-hôtes : utilisez un réseau overlay avec Swarm pour connecter les services entre les nœuds.

- Créer le réseau

- Bridge (défini par l'utilisateur) : docker network create app-net

- Host : pas d'étape de création de réseau ; vous attachez avec --network host

- Overlay : docker swarm init ; puis docker network create -d overlay --attachable app-ol

- Exécuter les services sur le réseau choisi

- Bridge : attachez avec --network app-net ou via les réseaux Compose

- Host : lancez avec --network host ; assurez-vous que l'application lie sur 0.0.0.0

- Overlay : utilisez des services ( docker service ... ) ou un fichier stack ( docker stack deploy )

- Publier seulement ce qui est nécessaire

- Conteneurs bridge/overlay : publiez les ports de l'hôte avec -p ou ports dans Compose

- Réseau host : ignorez -p ; le conteneur utilise la pile de l'hôte directement

- Vérifier et documenter

- Depuis un conteneur : résoudre le pair par nom ( curl http://api:8080 )

- Depuis l'hôte : atteindre les ports publiés ( curl http://localhost:8080 )

- Noter les ports et réseaux choisis pour réutilisation

## Réseau bridge en pratique (défaut local)

Un réseau bridge défini par l'utilisateur isole le trafic et active le DNS par nom de service par défaut. Préférez-le au bridge hérité par défaut appelé bridge .

Créer un réseau :

docker network create app-net 
 Exécuter une base de données et une API sur le même réseau :

# PostgreSQL
docker run -d \
 --name db \
 --network app-net \
 -e POSTGRES_PASSWORD=secret \
 postgres:16

# API simple écoutant sur 8080 et utilisant DATABASE_HOST=db
docker run -d \
 --name api \
 --network app-net \
 -e DATABASE_HOST=db \
 -p 8080:8080 \
 myorg/api:latest 
 Ce que vous obtenez :

- DNS conteneur-à-conteneur : db se résout à l'intérieur du réseau ; l'API peut se connecter à db:5432

- Accès hôte : les clients ou vos tests atteignent http://localhost:8080 grâce à -p 8080:8080

- Isolation : les autres réseaux ne peuvent pas atteindre ces conteneurs par nom

Vérifier le DNS depuis l'intérieur d'un conteneur :

docker exec -it api sh -lc 'ping -c1 db || true'; \
 docker exec -it api sh -lc 'getent hosts db || true' 

### Exemple minimal de Dockerfile pour l'API

 # Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY app.py .
RUN pip install --no-cache-dir flask psycopg2-binary
ENV PORT=8080
CMD ["python", "app.py 
 Exemple app.py (très petit) :

from flask import Flask
import os
app = Flask(__name__)

@app.get(\"\\)
def hello():
 return {"ok": True, "port": os.getenv("PORT", "8080\)}

app.run(host=\"0.0.0.0\", port=int(os.getenv(\"PORT\", \"8080\\))) 
 Construire et lancer :

docker build -t myorg/api:latest . 

## Bases de la publication de ports

- Syntaxe : -p portHote:portConteneur[/protocole]

- La publication expose un port de conteneur sur l'hôte. À l'intérieur du réseau Docker, les autres conteneurs se connectent toujours au port du conteneur, pas au port de l'hôte.

- Sur réseau host : n'utilisez pas -p . Votre application doit lier sur 0.0.0.0 et le port doit être libre sur l'hôte.

- Vous pouvez exécuter plusieurs conteneurs qui écoutent sur le même port de conteneur si vous publiez différents ports hôtes (ex. -p 8081:8080 et -p 8082:8080 ).

 Vérifier les ports publiés :

docker ps --format 'table {{.Names}}\t{{.Ports}}' 

## DNS entre conteneurs

 Sur les réseaux bridge définis par l'utilisateur et overlay, Docker fournit un résolveur DNS embarqué. Les conteneurs se résolvent mutuellement par nom :

- Hôte unique : utilisez le nom du conteneur sur le même bridge défini par l'utilisateur (ex. http://api:8080 )

- Compose : utilisez le nom du service (ex. http://web:80 )

À l'intérieur d'un conteneur, /etc/resolv.conf pointe généralement vers 127.0.0.11 , le serveur DNS de Docker pour le réseau.

## Réseaux Docker Compose (recommandé pour les stacks d'applications)

Docker Compose crée automatiquement un réseau dédié pour votre projet et donne à chaque service un nom DNS égal à sa clé de service. C'est le patron local le plus reproductible.

compose.yaml :

version: \"3.9\"
services:
 db:
 image: postgres:16
 environment:
 POSTGRES_PASSWORD: secret
 networks: [app-net]

 api:
 build: .
 environment:
 DATABASE_HOST: db
 ports:
 - \"8080:8080\"
 depends_on: [db]
 networks: [app-net]

 web:
 image: nginx:alpine
 ports:
 - \"8081:80\"
 networks: [app-net]

networks:
 app-net:
 driver: bridge 
 Utilisation :

docker compose up -d
# Test service-à-service
docker compose exec web sh -lc 'wget -qO- http://api:8080 || curl -s http://api:8080'
# Test depuis l'hôte
curl -s http://localhost:8081 

## Réseau host (Linux uniquement dans la plupart des cas)

 Le réseau host place le conteneur sur la pile réseau de l'hôte. Avantages : pas de NAT, surcharge réduite, trafic entrant plus simple. Inconvénients : moins d'isolation, conflits de ports, et généralement Linux uniquement.

Exemple :

# Assurez-vous que votre application lie sur 0.0.0.0:8080
docker run -d --name fastapi --network host myorg/api:latest
# Maintenant l'application est accessible sur l'hôte au port :8080 sans -p 
 Envisagez le mode host seulement quand vous en avez vraiment besoin et comprenez les compromis sécurité et opérationnels.

## Réseau overlay (multi-hôtes avec Swarm)

Les réseaux overlay connectent les services entre plusieurs hôtes Docker. Vous avez besoin de Swarm activé.

Initialiser Swarm et créer un overlay attachable :

docker swarm init
# Créer un réseau overlay que services et conteneurs standalone peuvent utiliser
docker network create -d overlay --attachable app-ol 
 Déployer des services avec ports publiés :

# Service API
docker service create \
 --name api \
 --network app-ol \
 -p 8080:8080 \
 myorg/api:latest

# Service web
docker service create \
 --name web \
 --network app-ol \
 -p 80:80 \
 nginx:alpine 
 Ou utilisez un fichier stack ( stack.yaml ) :

version: \"3.9\"
services:
 api:
 image: myorg/api:latest
 ports: [\"8080:8080\\)
 networks: [app-ol]
 web:
 image: nginx:alpine
 ports: [\"80:80\\)
 networks: [app-ol]
networks:
 app-ol:
 driver: overlay 
 Déployer la stack :

docker stack deploy -c stack.yaml mystack 
 Vérifier :

docker service ls
curl -s http://<ip-n'importe-quel-noeud>:80 

## Dépannage de la connectivité cassée

 Utilisez cette liste de contrôle pour isoler rapidement les problèmes courants.

- Les conteneurs sont-ils sur le même réseau ?

docker network inspect app-net --format '{{json .Containers}}' | jq '.' 
 Si le pair n'est pas listé, connectez-le :

docker network connect app-net api 

- Le port est-il réellement publié sur l'hôte ?

 docker ps --format 'table {{.Names}}\t{{.Ports}}'
# Cherchez 0.0.0.0:8080->8080/tcp (ou votre IP/port hôte choisi) 
 Si manquant, ajoutez -p ou ports dans Compose.

- L'application lie-t-elle sur 0.0.0.0 à l'intérieur du conteneur ?

# Remplacez par un outil disponible dans votre image
docker exec -it api sh -lc 'ss -tln || netstat -tln' 
 Si elle lie seulement sur 127.0.0.1 , mettez à jour l'application pour écouter sur 0.0.0.0 .

- Les conteneurs peuvent-ils se résoudre mutuellement par nom ?

docker exec -it api sh -lc 'getent hosts db || ping -c1 db || nslookup db || true' 
 Si la résolution échoue, assurez-vous d'utiliser un bridge défini par l'utilisateur ou un overlay et que les deux conteneurs rejoignent le même réseau.

- Pare-feu hôte bloquant le trafic ?

- Assurez-vous que votre hôte autorise l'entrant sur les ports publiés (ex. 80, 8080). Ajustez vos règles de pare-feu si nécessaire.

- Conflits de ports sur l'hôte ?

# Sur Linux
ss -tulpn | grep :8080 || netstat -tulpn | grep :8080 
 Si un processus utilise déjà le port hôte, choisissez-en un autre ou arrêtez le service conflictuel.

- Vérifications spécifiques à l'overlay

docker info | grep -i swarm
# Doit afficher : Swarm: active

docker service ps api 
 Si les tâches échouent, vérifiez les logs et la disponibilité des nœuds. Assurez-vous que tous les services s'attachent au même overlay.

Si vous avez utilisé le réseau bridge hérité par défaut, passez à un bridge défini par l'utilisateur pour un meilleur DNS et une meilleure isolation :

docker network create app-net
# Recréer les conteneurs avec --network app-net 
 En cas de doute, supprimez et recréez les conteneurs avec réseaux et ports explicites :

docker rm -f api db web || true
docker network rm app-net || true 
 Puis relancez les commandes connues bonnes ou Compose.

## Plan pilote local

Gardez le premier pilote petit, mesurable et facile à inspecter localement.

Objectif

- Une stack 3 services (db, api, web) sur un bridge défini par l'utilisateur avec DNS et ports publiés fonctionnels.

- Métrique de succès : curl depuis l'hôte retourne le JSON attendu et la page d'accueil Nginx en moins de 200 ms sur localhost.

Étapes

- Construire l'image API et créer le réseau

docker build -t myorg/api:latest .
docker network create app-net 

- Démarrer les services

 docker run -d --name db --network app-net -e POSTGRES_PASSWORD=secret postgres:16
docker run -d --name api --network app-net -e DATABASE_HOST=db -p 8080:8080 myorg/api:latest
docker run -d --name web --network app-net -p 8081:80 nginx:alpine 

- Vérifier

 # DNS conteneur-à-conteneur
docker exec web sh -lc 'wget -qO- http://api:8080 || curl -s http://api:8080'
# Accès hôte
curl -sS http://localhost:8080
curl -sS http://localhost:8081 

- Documenter les ports et le nom du réseau pour réutilisation dans les futurs services.

 Pilote optionnel suivant (overlay)

- Activer Swarm et répéter avec un réseau overlay sur deux hôtes ou deux VMs.

## Conclusion

- Utilisez un bridge défini par l'utilisateur pour la plupart des applications sur hôte unique. Vous obtenez isolation, DNS prévisible entre conteneurs, et publication de ports simple.

- Envisagez le réseau host seulement sur Linux et seulement quand vous avez besoin de surcharge réduite et comprenez les compromis.

- Utilisez les réseaux overlay avec Swarm pour les configurations multi-hôtes.

- Publiez seulement les ports nécessaires, vérifiez depuis l'hôte et entre conteneurs, et gardez une liste de contrôle de dépannage courte à portée de main.

- Commencez avec un petit pilote local mesurable, puis étendez le même patron à plus de services et, quand nécessaire, à plusieurs hôtes.