E-NO
DevOps 7 min de lecture

Docker Compose pour des workflows de développement locaux proches de la production : guide pratique

calendar_today Publié : 2026-07-08
update Dernière mise à jour : 2026-07-08
analytics Efficacité SEO : 97%
Illustration du guide technique pour « Docker Compose pour des workflows de développement locaux proches de la production : guide pratique ».

Introduction

Un environnement local proche de la production se rentabilise rapidement. Lorsque votre application, la base de données, le cache et le proxy tournent ensemble sous Docker Compose avec des réglages réalistes, vous détectez les problèmes d'intégration plus tôt, déboguez plus vite et réduisez les surprises en staging et en production. Ce guide montre comment bâtir cette configuration avec des services, des réseaux, des volumes, des fichiers d'environnement, des vérifications de santé et un workflow de débogage pratique.

Aperçu du workflow

Utilisez une boucle simple qui reflète la manière dont le logiciel est livré :

  1. Planifier
  • Lister les services et leurs communications (ports, protocoles, variables d'environnement).
  • Décider des réseaux, volumes et critères de santé pour chaque service.
  1. Construire
  • Créer des Dockerfiles proches de la production (images légères, utilisateur non-root, versions épinglées).
  • Utiliser docker build ou laisser Compose builder à partir de votre Dockerfile.
  1. Exécuter
  • Démarrer la pile avec docker compose up -d.
  • Attendre que les health checks deviennent « healthy ».
  1. Tester
  • Envoyer du trafic par le point d'entrée public (par exemple Nginx sur le port 80).
  • Valider la disponibilité (readiness), la vivacité (liveness) et les cas d'usage principaux.
  1. Itérer
  • Modifier configs ou code, reconstruire et relancer.

Cette séparation claire des étapes aide à garder les changements compréhensibles et réduit le retravail.

Conception du fichier Compose

Voici un docker-compose.yml pratique pour une petite pile web : une application Node.js, Postgres, Redis et Nginx comme proxy d'entrée. Il utilise deux réseaux (frontend et backend), des volumes nommés pour les données, des fichiers d'environnement pour la configuration et des health checks avec ordonnancement au démarrage.

version: '3.9'

services:
  web:
    build:
      context: ./web
      image: local/web:dev
    ports:
      - '8080:3000'
    env_file:
      - ./env/web.env
    environment:
      - NODE_ENV=development
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy
    healthcheck:
      test: ['CMD-SHELL', 'wget -qO- http://localhost:3000/health || exit 1']
      interval: 10s
      timeout: 3s
      retries: 5
      start_period: 15s
    volumes:
      - ./web:/app:cached
      - web-node-modules:/app/node_modules
    networks:
      - frontend
      - backend

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: app
      POSTGRES_DB: appdb
    volumes:
      - db-data:/var/lib/postgresql/data
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -U app -d appdb']
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - backend

  redis:
    image: redis:7-alpine
    command: ['redis-server', '--appendonly', 'yes']
    volumes:
      - redis-data:/data
    healthcheck:
      test: ['CMD', 'redis-cli', 'ping']
      interval: 10s
      timeout: 3s
      retries: 5
    networks:
      - backend

  nginx:
    image: nginx:1.25-alpine
    depends_on:
      web:
        condition: service_healthy
    ports:
      - '80:80'
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d:ro
    networks:
      - frontend

volumes:
  db-data:
  redis-data:
  web-node-modules:

networks:
  frontend:
  backend:

Exemple de configuration Nginx

Achemine le trafic du port 80 vers le service web.

# ./nginx/conf.d/app.conf
server {
  listen 80;
  server_name _;

  location / {
    proxy_pass http://web:3000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }

  location /healthz {
    return 200 'ok';
    add_header Content-Type text/plain;
  }
}

Exemple de Dockerfile Node.js

Restez proche de la production : base minimale, utilisateur non-root, version épinglée et un endpoint de santé simple dans votre application à /health.

# ./web/Dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
RUN addgroup -S app && adduser -S app -G app && chown -R app:app /app
USER app
EXPOSE 3000
CMD node server.js

Exemple d'application Node minimale

// ./web/server.js
const express = require('express');
const app = express();
const port = 3000;

app.get('/health', (req, res) => res.send('ok'));
app.get('/', (req, res) => res.send('Hello from web via Nginx'));

app.listen(port, () => console.log(`web listening on ${port}`));

Variables d'environnement et secrets

Utilisez un fichier .env au niveau du projet pour les variables de Compose, et des fichiers d'environnement par service pour les réglages de l'application.

  • Le .env du projet contrôle le comportement de Compose et les valeurs partagées.
  • Les fichiers d'environnement des services contrôlent les paramètres applicatifs.
  • Ne commettez pas de vrais secrets. Fournissez des fichiers d'exemple et chargez les valeurs réelles depuis un emplacement sécurisé.

Exemple de .env du projet :

# ./.env
COMPOSE_PROJECT_NAME=prodlike
WEB_PORT=8080

Exemple de fichier d'environnement de service :

# ./env/web.env
PORT=3000
DATABASE_URL=postgresql://app:app@db:5432/appdb
REDIS_URL=redis://redis:6379/0

Vous pouvez référencer ${WEB_PORT} dans votre fichier compose si vous préférez éviter les ports en dur.

Vérifications de santé et ordre de démarrage

Les health checks rendent la disponibilité des dépendances explicite. Utilisez healthcheck dans chaque service et depends_on avec condition: service_healthy dans les services dépendants. Cela empêche le service web de démarrer avant que la base de données ne soit prête.

  • Santé du web : GET /health renvoie 200.
  • Santé de Postgres : pg_isready réussit.
  • Santé de Redis : redis-cli ping renvoie PONG.

Compose affiche l'état de santé dans docker compose ps pour savoir quand la pile est prête.

Démarrage, test et itération

Démarrez la pile :

docker compose up -d --build

Vérifiez l'état et la santé :

docker compose ps
docker compose logs -f --tail=100 web db redis nginx

Testez via le proxy comme un utilisateur :

curl -sS http://localhost/

Options de rechargement à chaud :

  • Monter ./web en bind-mount dans le conteneur pour des éditions locales rapides.
  • Si vous avez besoin de nodemon, ajoutez-le dans devDependencies et lancez-le via un fichier compose d'override réservé au développement local.

Reconstruisez quand le Dockerfile change :

docker compose build web && docker compose up -d web

Débogage et résolution de problèmes

Vérifications et correctifs courants :

  • Conflits de ports
  • Symptôme : docker compose up n'arrive pas à exposer un port.
  • Correctif : changer les ports hôtes (ex. WEB_PORT), ou arrêter le processus en conflit.
  • Health check qui échoue en boucle
  • Consulter les logs du conteneur : docker compose logs web.
  • Entrer dans le conteneur et appeler l'endpoint de santé localement : docker compose exec web sh -lc 'wget -qO- http://localhost:3000/health'.
  • Vérifier que les variables d'environnement sont définies : docker compose exec web env | sort.
  • L'application ne rejoint pas la base de données ou Redis
  • Vérifier la résolution DNS dans le réseau : docker compose exec web getent hosts db redis.
  • Tester la connectivité TCP : docker compose exec web sh -lc 'nc -zv db 5432' et nc -zv redis 6379.
  • Permissions de volume sous Linux
  • Symptôme : EACCES à l'écriture.
  • Correctif : aligner l'UID/GID du conteneur sur celui de l'utilisateur hôte, ou chown le répertoire de travail pendant le build comme montré dans le Dockerfile.
  • Synchronisation de fichiers lente sur macOS/Windows
  • Symptôme : rechargement à chaud lent.
  • Correctif : utiliser l'option :cached, déplacer les dépendances lourdes vers un volume nommé (web-node-modules), ou reconstruire les images plus souvent au lieu de tout monter en live.
  • Données réinitialisées de façon inattendue
  • S'assurer d'utiliser des volumes nommés (db-data, redis-data) plutôt que des volumes anonymes.
  • docker compose down -v supprime les volumes nommés ; à utiliser avec précaution.
  • Environnement non appliqué
  • Vérifier l'ordre de résolution : .env, shell, env_file.
  • Afficher la config finale : docker compose config.

Commandes utiles :

docker compose config
docker compose ps --format json | jq '.'
docker compose logs -f web
docker compose exec -it web sh
docker compose inspect web

# Réseaux et volumes
docker network ls
docker network inspect prodlike_backend
docker volume ls

Plan pilote local

Commencez petit, mesurez, puis élargissez.

Périmètre

  • Services : web + db uniquement.
  • Critères de succès :
  • Temps entre docker compose up -d et les deux services « healthy » < 15 secondes sur votre machine.
  • curl http://localhost/ renvoie 200 et le contenu attendu.
  • docker compose restart web revient à « healthy » en < 5 secondes.

Étapes

  1. Implémenter les endpoints de santé et les checks pour web et db.
  2. Ajouter un volume nommé pour les données Postgres.
  3. Brancher l'environnement via ./env/web.env et ./.env.
  4. Mesurer les temps de référence avec les commandes de ce guide.
  5. Ajouter Redis et Nginx quand le pilote atteint les critères de succès.

Pourquoi ça fonctionne

  • Un périmètre étroit est plus simple à déboguer et à comprendre.
  • Des résultats clairs et mesurables indiquent quand faire grandir la pile.

Conclusion

Une configuration Docker Compose proche de la production vous donne un retour rapide et réaliste sans quitter votre poste de travail. Modélisez votre pile avec des services, réseaux et volumes ; configurez via des fichiers d'environnement ; et utilisez des health checks ainsi qu'un workflow reproductible pour réduire le retravail. Lancez un pilote étroit, mesurez les résultats, puis étendez vers une parité complète.

Recherches connexes

Score de qualité de l’article

Utilité pour le lecteur 97%
  • check_circle Guide prêt à lire
  • check_circle Exemples pratiques inclus
  • check_circle URL d’article optimisée pour le SEO