Docker y Kotlin: contenerización de aplicaciones para desarrolladores

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Docker y Kotlin: contenerización de aplicaciones



El desarrollo moderno con Kotlin requiere cada vez más el uso de contenerización. Docker permite empaquetar la aplicación junto con todas sus dependencias en un entorno aislado, lo que garantiza un comportamiento idéntico en la máquina local del desarrollador, el servidor de pruebas y producción. En este artículo, analizaremos cómo contenerizar correctamente proyectos Kotlin utilizando las mejores prácticas y ejemplos de código.



¿Por qué contenerizar aplicaciones Kotlin?



Kotlin funciona sobre la JVM, por lo que las aplicaciones heredan todas las características del ecosistema Java. Las principales ventajas de la contenerización son:



  • Reproducibilidad del entorno — evitamos problemas del tipo "en mi máquina funciona".
  • Aislamiento de dependencias — las versiones de JDK, librerías y utilidades del sistema se fijan en la imagen.
  • Escalabilidad — los contenedores se despliegan fácilmente en Kubernetes y otros orquestadores.
  • Despliegue rápido — las imágenes Docker son más pequeñas que las máquinas virtuales.


Creación de un Dockerfile para una aplicación Kotlin



Consideremos un proyecto típico en Kotlin que utiliza Gradle. Nuestro build.gradle.kts podría verse así:



plugins {    kotlin("jvm") version "1.9.22"    application}

application { mainClass.set("com.example.MainKt")}

dependencies { implementation(kotlin("stdlib")) // otras dependencias}


Ahora crearemos un Dockerfile. La primera opción es una compilación multi-etapa (multistage build), que separa la fase de compilación de la fase de ejecución:



# Etapa de compilaciónFROM gradle:8.5-jdk21 AS buildCOPY --chown=gradle:gradle . /home/gradle/srcWORKDIR /home/gradle/srcRUN gradle build --no-daemon

# Etapa de ejecuciónFROM eclipse-temurin:21-jre-alpineWORKDIR /appCOPY --from=build /home/gradle/src/build/libs/*.jar app.jarEXPOSE 8080ENTRYPOINT ["java", "-jar", "app.jar"]


Analicemos los puntos clave:



  • gradle:8.5-jdk21 — imagen oficial con Gradle y JDK para la compilación.
  • eclipse-temurin:21-jre-alpine — imagen ligera de JRE sobre Alpine Linux (aproximadamente 80 MB).
  • COPY --from=build — copiamos solo el JAR compilado, excluyendo los fuentes y la caché de Gradle.
  • EXPOSE 8080 — indicamos documentalmente el puerto (no lo abre automáticamente).


Para compilar la imagen, ejecute:



docker build -t kotlin-app:latest .docker run -p 8080:8080 kotlin-app:latest


Optimización del tamaño de la imagen



El tamaño de la imagen es crítico para la velocidad de despliegue. Aquí hay algunas técnicas para aplicaciones Kotlin:



1. Uso de jlink para crear una JRE personalizada



Si su aplicación no utiliza todos los módulos del JDK, puede crear una JRE mínima:



# Etapa de compilaciónFROM gradle:8.5-jdk21 AS buildCOPY . /appWORKDIR /appRUN gradle build --no-daemon

# Etapa de creación de JRE personalizadaFROM 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

# Etapa finalFROM 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"]


Este enfoque reduce el tamaño de la imagen de ~200 MB a ~40-50 MB.



2. Uso de Spring Boot layertools



Para proyectos Spring Boot (con Kotlin), puede dividir el JAR en capas para el almacenamiento en caché de Docker:



# build.gradle.ktstasks.bootJar {    layered {        enabled = true    }}


En el Dockerfile, copie las capas por separado,

Blogs

Book Recommendations