Docker y Kotlin: contenedorización de aplicaciones de nivel avanzado

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: contenedorización de aplicaciones de nivel avanzado



La contenedorización se ha convertido en una parte esencial del desarrollo moderno. Si ya dominas los principios básicos de Docker y has escrito algunas imágenes simples en Kotlin, es hora de pasar al siguiente nivel. En este artículo, analizaremos técnicas avanzadas: compilación en múltiples etapas, optimización del tamaño de la imagen final, trabajo con frameworks populares (Ktor, Spring Boot) y gestión eficiente de corrutinas en un entorno contenedorizado.



1. Compilación en múltiples etapas (Multi-stage builds)



Uno de los principales problemas al contenedorizar aplicaciones JVM es el tamaño de la imagen. Una imagen base de JDK puede pesar cientos de megabytes. La compilación en múltiples etapas permite separar las fases de compilación y ejecución, dejando en la imagen final solo la JRE y el JAR compilado.



Consideremos un ejemplo para una aplicación Kotlin compilada con Gradle:



# Etapa de compilaciónFROM gradle:7.6-jdk17 AS builderWORKDIR /appCOPY build.gradle.kts settings.gradle.kts ./COPY src ./srcRUN gradle build --no-daemon -x test

# Etapa de ejecuciónFROM eclipse-temurin:17-jre-alpineWORKDIR /appCOPY --from=builder /app/build/libs/*.jar app.jarEXPOSE 8080CMD ["java", "-jar", "app.jar"]


¿Por qué es efectivo?

  • En la etapa de compilación se utiliza el JDK completo y Gradle, pero no llegan a la imagen final.
  • La imagen final contiene solo la JRE (Java Runtime Environment), lo que reduce el tamaño entre 3 y 5 veces.
  • Alpine Linux reduce aún más el volumen a ~150-200 MB en lugar de 600+ MB.


2. Optimización de capas y almacenamiento en caché



Docker almacena en caché las capas, pero solo si no han cambiado. Para acelerar las compilaciones repetidas, separa las dependencias y el código fuente:



FROM gradle:7.6-jdk17 AS builderWORKDIR /app

# Primero copiamos solo los archivos de dependenciasCOPY build.gradle.kts settings.gradle.kts ./RUN gradle dependencies --no-daemon

# Luego el código fuente (cambia con más frecuencia)COPY src ./srcRUN gradle build --no-daemon -x test


Este enfoque garantiza que la capa con dependencias se reconstruya solo cuando cambie build.gradle.kts. De lo contrario, Docker usa la caché, ahorrando minutos en cada iteración.



Consejo: para proyectos Kotlin con muchas dependencias (por ejemplo, Spring Boot), esta técnica es especialmente relevante: la carga de la caché de Gradle puede llevar hasta 2-3 minutos.



3. Contenedorización de aplicaciones Ktor



Ktor es un framework asíncrono ligero en Kotlin, ideal para microservicios. La contenedorización de una aplicación Ktor requiere una configuración mínima, pero hay matices relacionados con las corrutinas.



Ejemplo de Dockerfile para Ktor:



FROM gradle:7.6-jdk17 AS builderWORKDIR /appCOPY build.gradle.kts settings.gradle.kts ./RUN gradle dependencies --no-daemonCOPY src ./srcRUN gradle build --no-daemon -x test

FROM eclipse-temurin:17-jre-alpineWORKDIR /appCOPY --from=builder /app/build/libs/ktor-app-*.jar app.jarEXPOSE 8080

# Importante: configuración de JVM para corrutinasCMD ["java", "-XX:+UseZGC", "-Xms256m", "-Xmx512m", "-jar", "app.jar"]


Puntos clave:

  • Usa ZGC (Z Garbage Collector) — minimiza las pausas, lo cual es crítico para aplicaciones asíncronas con muchas corrutinas.
  • Limita la memoria mediante -Xms y -Xmx. En contenedores, esto ayuda a evitar errores OOM.
  • Asegúrate de que el servidor Ktor no bloquee el hilo principal: las corrutinas deben configurarse mediante Dispatchers.IO o un pool personalizado.


Ejemplo de configuración de Ktor para trabajar en un contenedor:



fun main() {    embeddedServer(Netty, port = 8080, host = "0.0.0.0") {        routing {            get("/") {                

Blogs

Book Recommendations