Docker et Kotlin : conteneurisation d'applications
Le développement moderne en Kotlin nécessite de plus en plus l'utilisation de la conteneurisation. Docker permet d'empaqueter une application avec toutes ses dépendances dans un environnement isolé, garantissant ainsi un comportement identique sur la machine locale du développeur, le serveur de test et en production. Dans cet article, nous allons voir comment conteneuriser correctement les projets Kotlin, en utilisant les meilleures pratiques et des exemples de code.
Pourquoi conteneuriser les applications Kotlin ?
Kotlin fonctionne sur la JVM, donc les applications qui l'utilisent héritent de toutes les particularités de l'écosystème Java. Les principaux avantages de la conteneurisation sont :
- Reproductibilité de l'environnement — on évite les problèmes du type "ça marche sur ma machine".
- Isolation des dépendances — les versions du JDK, des bibliothèques et des utilitaires système sont figées dans l'image.
- Passage à l'échelle — les conteneurs se déploient facilement dans Kubernetes et d'autres orchestrateurs.
- Déploiement rapide — les images Docker sont plus petites que les machines virtuelles.
Création d'un Dockerfile pour une application Kotlin
Considérons un projet Kotlin typique utilisant Gradle. Notre build.gradle.kts pourrait ressembler à ceci :
plugins { kotlin("jvm") version "1.9.22" application}
application { mainClass.set("com.example.MainKt")}
dependencies { implementation(kotlin("stdlib")) // autres dépendances}Créons maintenant un Dockerfile. La première option est une construction en plusieurs étapes (multistage build), qui sépare l'étape de compilation de l'étape d'exécution :
# Étape de constructionFROM gradle:8.5-jdk21 AS buildCOPY --chown=gradle:gradle . /home/gradle/srcWORKDIR /home/gradle/srcRUN gradle build --no-daemon
# Étape d'exécutionFROM eclipse-temurin:21-jre-alpineWORKDIR /appCOPY --from=build /home/gradle/src/build/libs/*.jar app.jarEXPOSE 8080ENTRYPOINT ["java", "-jar", "app.jar"]Analysons les points clés :
- gradle:8.5-jdk21 — image officielle avec Gradle et JDK pour la construction.
- eclipse-temurin:21-jre-alpine — image JRE légère sur Alpine Linux (environ 80 Mo).
- COPY --from=build — on copie uniquement le JAR compilé, en excluant les sources et le cache Gradle.
- EXPOSE 8080 — indique le port à titre documentaire (ne l'ouvre pas automatiquement).
Pour construire l'image, exécutez :
docker build -t kotlin-app:latest .docker run -p 8080:8080 kotlin-app:latestOptimisation de la taille de l'image
La taille de l'image est cruciale pour la vitesse de déploiement. Voici quelques techniques pour les applications Kotlin :
1. Utilisation de jlink pour créer une JRE personnalisée
Si votre application n'utilise pas tous les modules du JDK, vous pouvez créer une JRE minimale :
# Étape de constructionFROM gradle:8.5-jdk21 AS buildCOPY . /appWORKDIR /appRUN gradle build --no-daemon
# Étape de création de la JRE personnaliséeFROM eclipse-temurin:21-jdk-alpine AS jre-builderRUN jlink \ --add-modules java.base,java.logging,java.naming,java.sql \ --strip-debug \ --no-man-pages \ --no-header-files \ --compress=2 \ --output /jre
# Étape finaleFROM alpine:3.19ENV JAVA_HOME=/jreENV PATH="${JAVA_HOME}/bin:${PATH}"COPY --from=jre-builder /jre /jreCOPY --from=build /app/build/libs/*.jar /app.jarEXPOSE 8080ENTRYPOINT ["java", "-jar", "/app.jar"]Cette approche réduit la taille de l'image d'environ 200 Mo à environ 40-50 Mo.
2. Utilisation de Spring Boot layertools
Pour les projets Spring Boot (avec Kotlin), vous pouvez diviser le JAR en couches pour la mise en cache Docker :
// build.gradle.ktstasks.bootJar { layered { enabled = true }}Dans le Dockerfile, copiez les couches séparément,