Optimizar Dockerización
Imágenes más pequeñas significan menos datos para transferir. Esto se traduce en descargas más rápidas desde los registros, implementaciones más ágiles y menor tiempo para escalar tus aplicaciones. Las imágenes más pequeñas a menudo conducen a tiempos de inicio de contenedor más rápidos.
Usa Imágenes Base Mínimas
Una de las formas más efectivas de reducir el tamaño de tu imagen Docker es comenzar con una imagen base mínima. La imagen base es la base de tu imagen Docker, y elegir la adecuada puede marcar una diferencia significativa.
En lugar de usar una imagen de sistema operativo completa como:
FROM ubuntu
Considera usar una alternativa más liviana:
FROM alpine
Alpine Linux es una distribución de Linux orientada a la seguridad y ligera, de solo 5 MB de tamaño. Es perfecta para crear imágenes Docker pequeñas y seguras. Sin embargo, usa musl libc
en lugar de glibc
, lo que puede ocasionar problemas de compatibilidad con algunas aplicaciones.
Para un enfoque aún más minimalista, especialmente para lenguajes compilados, considera usar imágenes sin distribución (distroless
):
FROM gcr.io/distroless/static-debian11
Las imágenes sin distribución contienen solo tu aplicación y sus dependencias de tiempo de ejecución. No contienen gestores de paquetes, shells, ni otros programas que esperarías encontrar en una distribución estándar de Linux. Esto las hace extremadamente pequeñas y seguras.
- Ubuntu: ~72MB
- Alpine: ~5MB
- Distroless: ~2MB
Construcciones Multi-etapa
Te permiten usar una imagen para compilar tu aplicación y otra para ejecutarla. Esta técnica es particularmente poderosa para lenguajes compilados, pero también puede ser útil para lenguajes interpretados.
# Etapa de construcciónFROM openjdk:11 AS builderCOPY . /app# Construye la aplicaciónRUN javac /app/Main.java
# Etapa finalFROM openjdk:11-jre# Copia el archivo binario precompilado de la etapa anteriorCOPY --from=builder /app/Main.class /app/# Comando para ejecutar el ejecutableCMD ["java", "-cp", "/app", "Main"]
O usa jlink para crear un custom JRE:
FROM openjdk:11 AS builderWORKDIR /appCOPY . .RUN jlink --add-modules java.base,java.logging --output /javaruntime
FROM alpine:3.18COPY --from=builder /javaruntime /opt/javaCOPY --from=builder /app/Main.class /app/ENV PATH="/opt/java/bin:${PATH}"CMD ["java", "-cp", "/app", "Main"]
Esto crea un JRE mínimo con sólo los módulos que su aplicación necesita.
O los jars por capas de Spring Boot::
FROM openjdk:11-jre as builderWORKDIR applicationCOPY target/*.jar application.jarRUN java -Djarmode=layertools -jar application.jar extract
FROM openjdk:11-jreWORKDIR applicationCOPY --from=builder application/dependencies/ ./COPY --from=builder application/spring-boot-loader/ ./COPY --from=builder application/snapshot-dependencies/ ./COPY --from=builder application/application/ ./ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]