Mise en conteneur d'une application Spring Boot avec Docker : guide pratique complet

Prérequis

Pourr suivre ce guide, vous aurez besoin de :

  • Docker Desktop (pour Windows/macOS) ou Docker Engine (pour Linux)
  • Un projet Spring Boot 3.x existant
  • Un JDK 17 ou supérieur

Structure du projet

Voici une structure de projet typique :

spring-boot-docker/
├── src/
├── Dockerfile
├── docker-compose.yml
└── .dockerignore

Création du Dockerfile

Un Dockerfile en deux étapes pour une image optimisée :

# Étape de construction
FROM maven:3.9-eclipse-temurin-17 AS construction
WORKDIR /opt/app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn clean package -DskipTests

# Étape d'exécution
FROM eclipse-temurin:17-jre-alpine
WORKDIR /opt/app

# Sécurité : utilisateur non-root
RUN addgroup -S groupe-app && adduser -S utilisateur -G groupe-app

COPY --from=construction /opt/app/target/*.jar app.jar
RUN chown -R utilisateur:groupe-app /opt/app
USER utilisateur

# Paramètres JVM
ENV JVM_OPTS="-Xms256m -Xmx512m"
ENV SPRING_PROFILES_ACTIVE=production

# Vérification de santé
HEALTHCHECK --interval=45s --timeout=4s \
  CMD wget -qO- http://localhost:8080/actuator/health > /dev/null || exit 1

EXPOSE 8080
ENTRYPOINT ["sh", "-c", "java $JVM_OPTS -jar app.jar"]

Fichier .dockerignore

Pour accélérer la consturction de l'image :

.git
*.iml
target/
*.md
Dockerfile
docker-compose.yml
log/
.idea/

Commandes de base Docker

Construire et gérer votre conteneur :

# Construction de l'image
docker build -t springboot-app:1.0 .

# Lancement du conteneur
docker run -d -p 8080:8080 --name mon-app springboot-app:1.0

# Consultation des logs
docker logs -f mon-app

# Connexion au conteneur
docker exec -it mon-app sh

Orchestration avec Docker Compose

Fichier de configuration complet avec une base de données :

version: '3.8'
services:
  application:
    build: .
    container_name: spring-app
    ports:
      - "8080:8080"
    environment:
      - SPRING_PROFILES_ACTIVE=production
      - SPRING_DATASOURCE_URL=jdbc:mysql://database:3306/appdb
      - SPRING_DATASOURCE_USER=appuser
      - SPRING_DATASOURCE_PASSWORD=secret
    depends_on:
      database:
        condition: service_healthy
    restart: always
    networks:
      - res-app

  database:
    image: mysql:8.0
    container_name: mysql-server
    environment:
      MYSQL_ROOT_PASSWORD: rootsecret
      MYSQL_DATABASE: appdb
      MYSQL_USER: appuser
      MYSQL_PASSWORD: secret
    volumes:
      - db-data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 15s
      timeout: 5s
      retries: 3
    networks:
      - res-app

volumes:
  db-data:

networks:
  res-app:
    driver: bridge

Conseils d'optimisation

1. Utilisation de registres miroirs

Configuration pour accélérer le téléchargement des images :

// /etc/docker/daemon.json
{
  "registry-mirrors": ["https://mirror.example.com"]
}

2. Réduction de la taille de l'image

  • Préférer les images Alpine Linux
  • Séparer les phases de construction et d'exécution
  • Utiliser un fichier .dockerignore complet

3. Bonnes pratiques de sécurité

  • Toujours exécuter l'application avec un utilisateur non privilégié
  • Limiter les ports exposés au strict nécessaire
  • Ne jamais stocker de secrets dans les images

Dépannage courant

Problème : Impossible de joindre la base de données depuis le conteneur

Solution : Utiliser l'adresse DNS interne de Docker Compose

jdbc:mysql://database:3306/appdb

Problème : Erreurs OutOfMemoryError

Solution : Ajuster les limites mémoire de la JVM dans le Dockerfile

ENV JVM_OPTS="-Xms256m -Xmx512m -XX:+UseG1GC"

Étiquettes: Docker Spring Boot Java Containerisation Déploiement

Publié le 14 juin à 03h02