0%
Déploiement avec Docker

Docker

Déploiement avec Docker

10-15 min

Déploiement avec Docker

Docker permet de conteneuriser et déployer facilement les microservices. Nous allons voir comment créer des images Docker et orchestrer le déploiement de nos services.

1. Configuration de Base

1.1 Dockerfile

# Stage de build
FROM eclipse-temurin:17-jdk-alpine AS build
WORKDIR /workspace/app
COPY mvnw .
COPY .mvn .mvn
COPY pom.xml .
COPY src src
RUN ./mvnw install -DskipTests
RUN mkdir -p target/dependency && (cd target/dependency; jar -xf ../*.jar)

# Stage de runtime
FROM eclipse-temurin:17-jre-alpine
VOLUME /tmp
ARG DEPENDENCY=/workspace/app/target/dependency
COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF
COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","com.example.product.ProductServiceApplication"]

1.2 Configuration Docker Compose

# docker-compose.yml
version: '3.8'

services:
  eureka-server:
    build: ./eureka-server
    ports:
      - "8761:8761"
    environment:
      - SPRING_PROFILES_ACTIVE=prod
    networks:
      - microservices-network

  config-server:
    build: ./config-server
    ports:
      - "8888:8888"
    environment:
      - SPRING_PROFILES_ACTIVE=prod
      - EUREKA_CLIENT_SERVICEURL_DEFAULTZONE=http://eureka-server:8761/eureka/
    depends_on:
      - eureka-server
    networks:
      - microservices-network

  api-gateway:
    build: ./api-gateway
    ports:
      - "8080:8080"
    environment:
      - SPRING_PROFILES_ACTIVE=prod
      - EUREKA_CLIENT_SERVICEURL_DEFAULTZONE=http://eureka-server:8761/eureka/
      - SPRING_CLOUD_CONFIG_URI=http://config-server:8888
    depends_on:
      - eureka-server
      - config-server
    networks:
      - microservices-network

  product-service:
    build: ./product-service
    ports:
      - "8081:8081"
    environment:
      - SPRING_PROFILES_ACTIVE=prod
      - EUREKA_CLIENT_SERVICEURL_DEFAULTZONE=http://eureka-server:8761/eureka/
      - SPRING_CLOUD_CONFIG_URI=http://config-server:8888
    depends_on:
      - eureka-server
      - config-server
    networks:
      - microservices-network

  order-service:
    build: ./order-service
    ports:
      - "8082:8082"
    environment:
      - SPRING_PROFILES_ACTIVE=prod
      - EUREKA_CLIENT_SERVICEURL_DEFAULTZONE=http://eureka-server:8761/eureka/
      - SPRING_CLOUD_CONFIG_URI=http://config-server:8888
    depends_on:
      - eureka-server
      - config-server
    networks:
      - microservices-network

  zipkin:
    image: openzipkin/zipkin
    ports:
      - "9411:9411"
    networks:
      - microservices-network

networks:
  microservices-network:
    driver: bridge

2. Optimisation des Images

2.1 Multi-stage Build

# Stage de build
FROM eclipse-temurin:17-jdk-alpine AS build
WORKDIR /workspace/app
COPY mvnw .
COPY .mvn .mvn
COPY pom.xml .
COPY src src
RUN ./mvnw install -DskipTests

# Stage de test
FROM build AS test
RUN ./mvnw test

# Stage de runtime
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY --from=build /workspace/app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app/app.jar"]

2.2 Optimisation des Layers

# Stage de build
FROM eclipse-temurin:17-jdk-alpine AS build
WORKDIR /workspace/app

# Copie des fichiers de dépendances
COPY pom.xml .
COPY mvnw .
COPY .mvn .mvn

# Téléchargement des dépendances
RUN ./mvnw dependency:go-offline

# Copie du code source
COPY src src

# Build de l'application
RUN ./mvnw clean package -DskipTests

# Stage de runtime
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY --from=build /workspace/app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app/app.jar"]

3. Configuration des Services

3.1 Variables d’Environnement

# application-prod.yml
spring:
  application:
    name: product-service
  datasource:
    url: jdbc:postgresql://postgres:5432/productdb
    username: ${DB_USERNAME}
    password: ${DB_PASSWORD}
  cloud:
    config:
      uri: http://config-server:8888
  zipkin:
    base-url: http://zipkin:9411

eureka:
  client:
    service-url:
      defaultZone: http://eureka-server:8761/eureka/

3.2 Health Checks

# docker-compose.yml
services:
  product-service:
    # ... autres configurations ...
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8081/actuator/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

4. Scripts de Déploiement

4.1 Script de Build

#!/bin/bash
# build.sh

# Build des images Docker
docker-compose build

# Push des images vers le registry
docker-compose push

4.2 Script de Déploiement

#!/bin/bash
# deploy.sh

# Pull des dernières images
docker-compose pull

# Démarrage des services
docker-compose up -d

# Attente de la disponibilité des services
echo "Waiting for services to be ready..."
sleep 30

# Vérification de la santé des services
docker-compose ps

5. Monitoring et Logging

5.1 Configuration des Logs

# docker-compose.yml
services:
  product-service:
    # ... autres configurations ...
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

5.2 Métriques Docker

# Affichage des statistiques des conteneurs
docker stats

# Affichage des logs
docker-compose logs -f product-service

6. Tests

6.1 Test d’Intégration Docker

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class DockerIntegrationTest {
    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    void whenGetProduct_thenProductIsReturned() {
        ResponseEntity<Product> response = restTemplate.getForEntity(
            "/api/products/1", Product.class);
        assertEquals(HttpStatus.OK, response.getStatusCode());
        assertNotNull(response.getBody());
    }
}

6.2 Test de Performance

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class DockerPerformanceTest {
    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    void whenMultipleRequests_thenResponseTimeIsAcceptable() {
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 100; i++) {
            restTemplate.getForEntity("/api/products/1", Product.class);
        }
        long endTime = System.currentTimeMillis();
        long averageTime = (endTime - startTime) / 100;
        assertTrue(averageTime < 100); // Moins de 100ms par requête
    }
}

Conclusion

Le déploiement avec Docker offre plusieurs avantages :

  • Environnement isolé et reproductible
  • Déploiement simplifié et automatisé
  • Scalabilité horizontale facilitée
  • Gestion efficace des dépendances
  • Monitoring et logging intégrés

Dans le prochain tutoriel, nous verrons comment orchestrer nos conteneurs Docker avec Kubernetes.

Commentaires

Les commentaires sont alimentés par GitHub Discussions

Connectez-vous avec GitHub pour participer à la discussion

Lien copié !