Docker Microservices Setup : De zéro à un environnement opérationnel

Docker Microservices Setup : De zéro à un environnement opérationnel
par Zelkulon19 mars 20251 min de lecture

Utiliser correctement Docker et Docker Compose pour les microservices : Builds multistages, découverte de services, health checks et un environnement de développement local complet.

Architecture Cible

┌─────────────────────────────────────────────────────────────┐
│                   docker-compose.yml                        │
│                                                             │
│  ┌──────────┐    ┌──────────┐    ┌──────────┐              │
│  │  Next.js │    │  Order   │    │  Payment │              │
│  │  :3000   │    │  Service │    │  Service │              │
│  └────┬─────┘    └────┬─────┘    └────┬─────┘              │
│       └───────────────┴───────────────┘                    │
│                    Bridge-Network                           │
│       ┌──────────┐   ┌──────────┐   ┌──────────┐           │
│       │PostgreSQL│   │ RabbitMQ │   │  Redis   │           │
│       │  :5432   │   │  :5672   │   │  :6379   │           │
│       └──────────┘   └──────────┘   └──────────┘           │
└─────────────────────────────────────────────────────────────┘

Dockerfile Multistage (Spring Boot)

# ─── Stage 1: Build ────────────────────────────────────────────
FROM eclipse-temurin:21-jdk-alpine AS build
WORKDIR /app

COPY pom.xml .
COPY .mvn .mvn
COPY mvnw .
RUN ./mvnw dependency:go-offline -B  # Cache de couche pour les dépendances

COPY src src
RUN ./mvnw package -DskipTests -B
RUN java -Djarmode=layertools -jar target/*.jar extract     --destination target/layers

# ─── Stage 2: Runtime (~150 Mo au lieu de ~600 Mo) ──────────────────
FROM eclipse-temurin:21-jre-alpine AS runtime
WORKDIR /app

COPY --from=build /app/target/layers/dependencies/          ./
COPY --from=build /app/target/layers/spring-boot-loader/    ./
COPY --from=build /app/target/layers/application/           ./

RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser

EXPOSE 8081
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s     CMD wget -qO- http://localhost:8081/actuator/health || exit 1

ENTRYPOINT ["java", "org.springframework.boot.loader.launch.JarLauncher"]

Docker Compose

services:
  postgres:
    image: postgres:16-alpine
    environment:
      POSTGRES_PASSWORD: ${DB_PASS:-secret}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      retries: 5

  rabbitmq:
    image: rabbitmq:3.13-management-alpine
    ports:
      - "5672:5672"
      - "15672:15672"  # Interface de gestion
    healthcheck:
      test: ["CMD", "rabbitmq-diagnostics", "ping"]
      interval: 30s

  order-service:
    build: ./order-service
    environment:
      SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/orderdb
      SPRING_RABBITMQ_HOST:  rabbitmq
    ports:
      - "8081:8081"
    depends_on:
      postgres:
        condition: service_healthy   # Démarrer uniquement quand la DB est prête !
      rabbitmq:
        condition: service_healthy
    restart: unless-stopped

volumes:
  postgres_data:

Commandes Utiles

# Démarrer tous les services
docker compose up -d

# Infrastructure uniquement (pour le développement local)
docker compose up -d postgres rabbitmq redis

# Logs d'un service
docker compose logs -f order-service

# Reconstruire le service
docker compose up -d --build order-service

# État de tous les services
docker compose ps

# Ouvrir le shell du conteneur
docker compose exec order-service sh

# Tout arrêter + supprimer les volumes (réinitialiser la base de données)
docker compose down -v

Séquence de Démarrage avec Health Checks

1. Démarrage de postgres, rabbitmq, redis
        │
        ▼
2. Health checks (pg_isready, rabbit ping, redis ping)
        │ tous sains
        ▼
3. Démarrage de order-service, payment-service
        │
        ▼
4. Health checks (actuator/health)
        │ tous sains
        ▼
5. Démarrage du frontend

Sans condition: service_healthy → Spring démarre avant que
PostgreSQL soit prêt → erreur de connexion !

Conclusion

  • Cohérence : "Ça marche sur ma machine" appartient au passé
  • Isolation : Les services fonctionnent sans dépendances mutuelles
  • Onboarding rapide : docker compose up – c'est prêt
  • Parité production : L'environnement local correspond exactement au déploiement
  • Scalabilité : docker compose up --scale order-service=3
Docker Microservices Setup : De zéro à un environnement opérationnel