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; puisdocker network create -d overlay --attachable app-ol
- Exécuter les services sur le réseau choisi
- Bridge : attachez avec
--network app-netou via les réseaux Compose - Host : lancez avec
--network host; assurez-vous que l'application lie sur0.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
-pouportsdans 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 :
dbse 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:8080grâ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 sur0.0.0.0et 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:8080et-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 :
curldepuis 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.