Docker y Kotlin: contenerizació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: contenerización de aplicaciones a nivel avanzado

\n\n

La contenerización se ha convertido en una parte integral del desarrollo moderno, y Kotlin no es una excepción. Si ya dominas los Dockerfile básicos y la ejecución de archivos JAR simples, es hora de pasar al siguiente nivel. En este artículo, exploraremos técnicas avanzadas de contenerización para aplicaciones Kotlin: compilación multi-etapa (multi-stage builds), optimización del tamaño de las imágenes, configuración para los frameworks Ktor y Spring Boot, así como el trabajo con Docker Compose en entornos de producción.

\n\n

1. Compilación multi-etapa de aplicaciones Kotlin

\n\n

Uno de los principales problemas al contenerizar aplicaciones JVM es el tamaño de la imagen final. Una imagen estándar de OpenJDK puede pesar más de 400 MB. La compilación multi-etapa permite separar el entorno de compilación del entorno de ejecución, utilizando una imagen de runtime mínima.

\n\n

Ejemplo para un proyecto Gradle en Kotlin

\n\n
# Primera etapa: compilación\nFROM gradle:8.5-jdk21 AS builder\nWORKDIR /app\nCOPY build.gradle.kts settings.gradle.kts ./\nCOPY src ./src\nRUN gradle build --no-daemon -x test\n\n# Segunda etapa: ejecución\nFROM eclipse-temurin:21-jre-alpine\nWORKDIR /app\nCOPY --from=builder /app/build/libs/app.jar app.jar\nEXPOSE 8080\nENTRYPOINT ["java", "-jar", "app.jar"]
\n\n

El uso de eclipse-temurin:21-jre-alpine en lugar de la imagen completa del JDK reduce el tamaño de 400+ MB a ~120 MB. Para aplicaciones Kotlin con Ktor o Spring Boot, esto es más que suficiente.

\n\n

Optimización del almacenamiento en caché de capas

\n\n

Para acelerar las compilaciones repetidas, copia las dependencias por separado del código fuente:

\n\n
FROM gradle:8.5-jdk21 AS builder\nWORKDIR /app\n# Primero las dependencias (se almacenan en caché si no cambian)\nCOPY build.gradle.kts settings.gradle.kts ./\nRUN gradle dependencies --no-daemon\n# Luego el código fuente\nCOPY src ./src\nRUN gradle build --no-daemon -x test
\n\n

Este truco es especialmente útil en CI/CD, donde cada segundo cuenta.

\n\n

2. Optimización de imágenes para aplicaciones Kotlin

\n\n

Además de elegir la imagen base, existen técnicas adicionales para reducir el tamaño y mejorar la seguridad.

\n\n

Uso de JLink para crear una JRE personalizada

\n\n

Si tu aplicación solo utiliza una parte de los módulos del JDK, puedes crear una JRE mínima:

\n\n
# En la etapa builder\nRUN jlink --module-path /opt/java/openjdk/jmods \\\n          --add-modules java.base,java.logging,java.naming,java.sql \\\n          --output /custom-jre \\\n          --strip-debug --no-man-pages --no-header-files\n\n# En la etapa runtime\nFROM alpine:3.19\nCOPY --from=builder /custom-jre /opt/jre\nCOPY --from=builder /app/build/libs/app.jar /app/app.jar\nENV PATH="/opt/jre/bin:${PATH}"\nEXPOSE 8080\nCMD ["java", "-jar", "/app/app.jar"]
\n\n

El tamaño de la imagen puede reducirse a 50-70 MB.

\n\n

Arquitectura multicapa con Spring Boot

\n\n

Spring Boot 3+ admite la división del fat JAR en capas. Úsalo en el Dockerfile:

\n\n
FROM eclipse-temurin:21-jre-alpine AS builder\nWORKDIR /app\nCOPY build/libs/*.jar app.jar\nRUN java -Djarmode=layertools -jar app.jar extract\n\nFROM eclipse-temurin:21-jre-alpine\nWORKDIR /app\nCOPY --from=builder /app/dependencies/ ./\nCOPY --from=builder /app/spring-boot-loader/ ./\nCOPY --from=builder /app/snapshot-dependencies/ ./\nCOPY --from=builder /app/application/ ./\nENTRYPOINT ["java", "org.springframework.boot.loader.launch.JarLauncher"]
\n\n

Ahora, al modificar el código, solo se reconstruye la capa application, mientras que las dependencias y el cargador de Spring Boot permanecen en caché.

\n\n

3. Contenerización de aplicaciones Ktor

\n\n

Ktor es un framework ligero para crear servidores asíncronos en Kotlin. Su contenerización tiene sus propias particularidades.

\n\n

Dockerfile para Ktor con Netty

\n\n
FROM gradle:8.5-jdk21 AS builder\nWORKDIR /app\nCOPY build.gradle.kts settings.gradle.kts ./\nRUN gradle dependencies --                

Blogs

Book Recommendations