Docker و Kotlin: حاويات التطبيقات
تتطلب التطوير الحديث بلغة Kotlin بشكل متزايد استخدام الحاويات. يتيح Docker تعبئة التطبيق مع جميع التبعيات في بيئة معزولة، مما يضمن سلوكًا متطابقًا على جهاز المطور المحلي وخادم الاختبار وبيئة الإنتاج. في هذه المقالة، سنشرح كيفية حاويات مشاريع Kotlin بشكل صحيح باستخدام أفضل الممارسات وأمثلة الكود.
لماذا حاويات تطبيقات Kotlin؟
تعمل Kotlin فوق JVM، لذا ترث التطبيقات المكتوبة بها جميع ميزات نظام Java البيئي. المزايا الرئيسية للحاويات:
- قابلية تكرار البيئة — نتجنب مشاكل "يعمل على جهازي".
- عزل التبعيات — يتم تثبيت إصدارات JDK والمكتبات والأدوات النظامية في الصورة.
- قابلية التوسع — يمكن نشر الحاويات بسهولة في Kubernetes ومنسقات أخرى.
- النشر السريع — صور Docker أصغر حجمًا من الأجهزة الافتراضية.
إنشاء Dockerfile لتطبيق Kotlin
لنفكر في مشروع Kotlin نموذجي يستخدم Gradle. قد يبدو ملف build.gradle.kts الخاص بنا كالتالي:
plugins { kotlin("jvm") version "1.9.22" application}
application { mainClass.set("com.example.MainKt")}
dependencies { implementation(kotlin("stdlib")) // تبعيات أخرى}الآن لننشئ Dockerfile. الخيار الأول هو البناء متعدد المراحل (multistage build)، الذي يفصل مرحلة التجميع عن مرحلة التنفيذ:
# مرحلة البناءFROM gradle:8.5-jdk21 AS buildCOPY --chown=gradle:gradle . /home/gradle/srcWORKDIR /home/gradle/srcRUN gradle build --no-daemon
# مرحلة التنفيذFROM eclipse-temurin:21-jre-alpineWORKDIR /appCOPY --from=build /home/gradle/src/build/libs/*.jar app.jarEXPOSE 8080ENTRYPOINT ["java", "-jar", "app.jar"]دعنا نشرح النقاط الرئيسية:
- gradle:8.5-jdk21 — الصورة الرسمية مع Gradle و JDK للبناء.
- eclipse-temurin:21-jre-alpine — صورة JRE خفيفة على Alpine Linux (حوالي 80 ميجابايت).
- COPY --from=build — ننسخ فقط ملف JAR المُجمَّع، مستبعدين المصدر وذاكرة التخزين المؤقت لـ Gradle.
- EXPOSE 8080 — نحدد المنفذ بشكل توثيقي (لا يفتحه تلقائيًا).
لبناء الصورة، نفذ:
docker build -t kotlin-app:latest .docker run -p 8080:8080 kotlin-app:latestتحسين حجم الصورة
حجم الصورة أمر بالغ الأهمية لسرعة النشر. إليك بعض التقنيات لتطبيقات Kotlin:
1. استخدام jlink لإنشاء JRE مخصصة
إذا كان تطبيقك لا يستخدم جميع وحدات JDK، يمكنك إنشاء JRE بأقل حجم:
# مرحلة البناءFROM gradle:8.5-jdk21 AS buildCOPY . /appWORKDIR /appRUN gradle build --no-daemon
# مرحلة إنشاء JRE مخصصةFROM 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
# المرحلة النهائيةFROM 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"]يقلل هذا الأسلوب حجم الصورة من ~200 ميجابايت إلى ~40-50 ميجابايت.
2. استخدام Spring Boot layertools
لمشاريع Spring Boot (مع Kotlin) يمكن تقسيم JAR إلى طبقات للتخزين المؤقت في Docker:
# build.gradle.ktstasks.bootJar { layered { enabled = true }}في Dockerfile، انسخ الطبقات بشكل منفصل،