Linux

Docker Compose avec Network

Créer un docker-compose.yml utilisant des réseaux Docker personnalisés pour isoler et connecter les services.

← Retour aux tutoriels Linux
📚 C'est quoi les réseaux Docker ? Quand vous avez plusieurs containers, parfois certains doivent se parler (un site web et sa base de données) mais d'autres ne doivent PAS pouvoir communiquer entre eux (pour la sécurité). Les réseaux Docker permettent de créer des groupes isolés : seuls les containers sur le même réseau peuvent se voir. C'est comme avoir des VLANs virtuels, mais pour vos containers.
ⓘ Environnement de travail Ce tuto est réalisé dans un environnement de test sous WSL avec VS Code. Docker Desktop doit être installé sur Windows avec l'intégration WSL activée.
⚠ Adaptez les sous-réseaux à votre environnement Les sous-réseaux 172.20.0.0/24 et 172.21.0.0/24 utilisés dans ce tuto sont des réseaux Docker internes. Si ces plages entrent en conflit avec votre réseau local, changez-les (ex: 172.30.0.0/24, 172.31.0.0/24). Ces réseaux sont internes à Docker et n'affectent pas votre réseau physique.

Comprendre les réseaux dans Docker Compose

Par défaut, Docker Compose crée un réseau unique pour tous les services d'un fichier. Mais on peut :

  • Créer plusieurs réseaux pour isoler certains services.
  • Contrôler la communication : seuls les services sur le même réseau peuvent communiquer.
  • Définir des sous-réseaux avec des plages IP spécifiques.

Schéma de l'architecture

┌────────────────────────────────────────────┐
│              frontend-net                  │
│   ┌──────────┐       ┌──────────────┐     │
│   │  Nginx   │       │   App Node   │     │
│   │ (proxy)  │──────▶│   (backend)  │     │
│   └──────────┘       └───────┬──────┘     │
│                              │             │
└──────────────────────────────┼─────────────┘
                               │
┌──────────────────────────────┼─────────────┐
│              backend-net     │             │
│                      ┌───────▼──────┐     │
│                      │  PostgreSQL  │     │
│                      │   (base)     │     │
│                      └──────────────┘     │
└────────────────────────────────────────────┘

Nginx est uniquement sur frontend-net. L'App est sur les deux réseaux. PostgreSQL est uniquement sur backend-net. Ainsi, Nginx ne peut pas accéder directement à la base.

Créer le projet

mkdir -p ~/compose-network
cd ~/compose-network
code .

Créer le docker-compose.yml

Créez le fichier docker-compose.yml dans VS Code :

services:

  # Reverse proxy - uniquement sur le réseau frontend
  nginx:
    image: nginx:alpine
    container_name: nginx-proxy
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
    networks:
      - frontend-net
    depends_on:
      - app

  # Application backend - sur les deux réseaux
  app:
    image: node:18-alpine
    container_name: app-backend
    working_dir: /app
    command: node server.js
    volumes:
      - ./app:/app
    networks:
      - frontend-net
      - backend-net
    depends_on:
      - db

  # Base de données - uniquement sur le réseau backend
  db:
    image: postgres:16
    container_name: postgres-db
    environment:
      POSTGRES_USER: appuser
      POSTGRES_PASSWORD: Password
      POSTGRES_DB: appdb
    volumes:
      - ./data/postgres:/var/lib/postgresql/data
    networks:
      - backend-net

networks:
  frontend-net:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.0.0/24    # ⭐ Adaptez si conflit avec votre réseau

  backend-net:
    driver: bridge
    ipam:
      config:
        - subnet: 172.21.0.0/24    # ⭐ Adaptez si conflit avec votre réseau

Créer les fichiers de l'application

Configuration Nginx

Créez nginx.conf à la racine du projet dans VS Code :

server {
    listen 80;

    location / {
        proxy_pass http://app:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Application Node.js simple

Créez le dossier app/ et le fichier app/server.js dans VS Code :

const http = require('http');

const server = http.createServer((req, res) => {
    res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
    res.end('<h1>App backend fonctionne !</h1><p>Connectée à PostgreSQL via backend-net</p>');
});

server.listen(3000, () => {
    console.log('Serveur démarré sur le port 3000');
});

Lancer et tester

# Démarre tous les services en arrière-plan
docker compose up -d

# Vérifie que les 3 containers tournent
docker compose ps

# Teste l'accès à l'application via Nginx (le reverse proxy)
# Vous devez voir le HTML de l'app Node.js
curl http://localhost

Vérifier l'isolation réseau

# TEST 1 : Nginx essaie de joindre PostgreSQL
# Résultat attendu : ÉCHEC ! Nginx est sur frontend-net, PostgreSQL sur backend-net
# Ils ne sont PAS sur le même réseau → Nginx ne peut pas voir la base de données
docker exec nginx-proxy ping -c 2 postgres-db
# → Résultat : ping: bad address 'postgres-db'

# TEST 2 : L'app essaie de joindre PostgreSQL
# Résultat attendu : SUCCÈS ! L'app est sur frontend-net ET backend-net
docker exec app-backend ping -c 2 postgres-db
# → Résultat : PING réussi

# TEST 3 : L'app essaie de joindre Nginx
# Résultat attendu : SUCCÈS ! Les deux sont sur frontend-net
docker exec app-backend ping -c 2 nginx-proxy
# → Résultat : PING réussi
✔ Isolation confirmée Nginx ne peut pas communiquer directement avec PostgreSQL — l'isolation réseau fonctionne !

Inspecter les réseaux

# Affiche tous les réseaux Docker (vous verrez frontend-net et backend-net)
docker network ls

# Inspecte le réseau frontend : quels containers y sont connectés ?
# Vous verrez nginx-proxy et app-backend avec leurs IP en 172.20.0.x
docker network inspect compose-network_frontend-net

# Inspecte le réseau backend : quels containers y sont connectés ?
# Vous verrez app-backend et postgres-db avec leurs IP en 172.21.0.x
docker network inspect compose-network_backend-net

Vous verrez les containers attachés à chaque réseau avec leurs adresses IP dans les sous-réseaux définis (172.20.0.x et 172.21.0.x).

Structure du dossier

compose-network/
├── docker-compose.yml
├── nginx.conf
├── app/
│   └── server.js
└── data/
    └── postgres/          # Données PostgreSQL
✔ Résultat Vous avez une architecture Docker Compose multi-réseau : le frontend est isolé du backend, et seule l'application peut communiquer avec les deux. Toutes les données sont dans ./data/, visible dans VS Code.