Comment j’ai conteneurisé une application Spring Boot avec Docker multi-stage

devops docker

Conteneuriser une application Java n’est pas aussi simple que d’écrire FROM openjdk et de copier un JAR. Dans cet article, je détaille la méthode que j’utilise en production pour construire des images Docker optimisées pour Spring Boot.

Le problème des images naïves

Un Dockerfile basique pour Spring Boot produit facilement une image de 400+ MB. C’est lent à pull, coûteux en stockage, et offre une surface d’attaque élargie. La solution : le multi-stage build.

Le Dockerfile optimisé

Le premier stage utilise maven:3.9-eclipse-temurin-21 pour builder l’application. Le deuxième stage utilise eclipse-temurin:21-jre-alpine — uniquement le JRE, pas le JDK complet. Résultat : une image de ~150 MB au lieu de 400+.

Mais on peut aller plus loin. Spring Boot 3.x supporte les layered JARs : au lieu de copier un seul fat JAR, on extrait les couches (dependencies, spring-boot-loader, snapshot-dependencies, application) dans des layers Docker séparées. Les dépendances changent rarement, donc Docker les cache et ne rebuild que la couche application à chaque commit.

Les bonnes pratiques

  • Utilisez un utilisateur non-root dans le container (USER 1001)
  • Ajoutez un healthcheck avec Spring Actuator (/actuator/health)
  • Définissez les limites JVM via -XX:MaxRAMPercentage=75 pour respecter les limits Kubernetes
  • Scannez l’image avec Docker Scout ou Trivy dans votre CI

Le temps de build passe de 3 minutes à 45 secondes grâce au cache des layers. En production, le cold start du container est de 8 secondes au lieu de 15.

Share: Partager :