Introduction à Docker et Java
Le développement moderne d'applications Java est impensable sans la conteneurisation. Docker est une plateforme pour empaqueter, livrer et exécuter des applications dans des environnements isolés (conteneurs). Pour les développeurs Java, Docker résout le problème éternel : « Sur ma machine, ça marche ! ». Le conteneur garantit que votre application s'exécutera de la même manière sur la machine locale, le serveur de développement et en production.
Dans cet article, nous allons voir comment conteneuriser des applications Java avec Docker : du simple Dockerfile à l'optimisation des images pour une architecture de microservices. Tous les exemples sont écrits en Java et prêts à être utilisés.
Fondamentaux de Docker pour les applications Java
Qu'est-ce qu'une image Docker et un conteneur ?
Une image Docker est un modèle (read-only) contenant tout le nécessaire pour exécuter une application : JVM, bibliothèques, code et configurations. Un conteneur est une instance en cours d'exécution de l'image. Pour Java, cela signifie que vous n'avez pas besoin d'installer manuellement le JDK sur le serveur — la JVM sera déjà à l'intérieur du conteneur.
Création d'un Dockerfile simple pour Java
Prenons un exemple basique. Nous avons une application Java simple (par exemple, HelloWorld.java).
// HelloWorld.javapublic class HelloWorld { public static void main(String[] args) { System.out.println("Hello from Docker and Java!"); }}Créons un Dockerfile :
# Utilisation de l'image officielle OpenJDKFROM openjdk:11-jre-slim
# Définition du répertoire de travailWORKDIR /app
# Copie du jar compilé ou des fichiers .classCOPY HelloWorld.class .
# Commande de lancementCMD ["java", "HelloWorld"]Construction et exécution :
# Construction de l'imagedocker build -t hello-java .
# Lancement du conteneurdocker run hello-javaSortie : Hello from Docker and Java!
Conteneurisation d'applications Spring Boot
Pour les projets réels (par exemple, avec Spring Boot), le processus se complexifie. Prenons un microservice typique.
Construction multi-étapes (Multi-stage build)
C'est la meilleure pratique pour Java : d'abord, on compile l'application avec le JDK complet, puis on copie le résultat dans une image JRE légère.
# Étape 1 : ConstructionFROM maven:3.8.5-openjdk-11 AS buildWORKDIR /appCOPY pom.xml .RUN mvn dependency:go-offlineCOPY src ./srcRUN mvn clean package -DskipTests
# Étape 2 : ExécutionFROM openjdk:11-jre-slimWORKDIR /appCOPY --from=build /app/target/*.jar app.jarEXPOSE 8080ENTRYPOINT ["java", "-jar", "app.jar"]Explication :
- build — utilise Maven et le JDK complet pour la compilation.
- Image finale — contient uniquement le JRE et le fichier jar prêt. La taille de l'image est réduite de 2 à 3 fois.
Optimisation de la mise en cache des couches
Docker met en cache chaque couche (instruction). Pour accélérer la construction, placez les dépendances rarement modifiées au début :
FROM maven:3.8.5-openjdk-11 AS buildWORKDIR /app# Mise en cache des dépendancesCOPY pom.xml .RUN mvn dependency:go-offline# Copie du code maintenantCOPY src ./srcRUN mvn clean packageDésormais, si vous modifiez uniquement le code, Docker ne reconstruira que les dernières couches, tandis que les dépendances seront prises depuis le cache.
Gestion des variables d'environnement et des profils
Passage de paramètres à une application Java
Docker permet de configurer flexiblement l'application via des variables d'environnement. Pour Spring Boot, c'est particulièrement pratique.
docker run -e SPRING_PROFILES_ACTIVE=prod -e DB_URL=jdbc:postgresql://db:5432/mydb my-appDans le Dockerfile, on peut définir des valeurs par défaut :
ENV SPRING_PROFILES_ACTIVE=devENV DB_URL=jdbc:h2:mem:testdbExemple de docker-compose pour Java + BDD
Pour les microservices, il est pratique d'utiliser docker-compose.yml :
version: '3.8'services: app: bu