مقدمة: لماذا تعتبر حاويات Swift تحدياً وميزة
\nلطالما اعتبرت حاويات تطبيقات Swift لنظامي iOS وmacOS مجالاً للمتحمسين. على عكس Go أو Node.js، تتطلب Swift التجميع على المنصة المستهدفة، وظلت صور Docker الرسمية لفترة طويلة نادرة. لكن مع إصدار Swift 5.x وظهور الصور الرسمية swift:5.10 (وما أحدث) تغير الوضع جذرياً. اليوم، لا يسمح Docker بتشغيل الخوادم الخلفية على Vapor فحسب، بل أيضاً بأتمتة بناء أدوات CLI، واختبار الكود في بيئة معزولة، وحتى إعداد القطع الأثرية الثنائية للنشر على macOS.
في هذه المقالة، سنستعرض التقنيات المتقدمة: البناء متعدد المراحل (multi-stage build)، التخزين المؤقت القوي للتبعيات، تحسين حجم الصورة، والتكامل مع Swift Package Manager. الأمثلة موجهة لمشاريع حقيقية - من خادم HTTP بسيط إلى خدمة مصغرة معقدة.
\n\n1. البناء متعدد المراحل: فصل التجميع عن وقت التشغيل
\nالخطأ الكلاسيكي للمبتدئين هو استخدام صورة واحدة للتجميع والتشغيل. ونتيجة لذلك، يزيد وزن الصورة عن 2 جيجابايت بسبب SDK والأدوات والمصادر. النهج الصحيح هو مرحلتان: builder وrunner.
\nمثال على Dockerfile لتطبيق Vapor
\n# المرحلة 1: البناء\nFROM swift:5.10 AS builder\nWORKDIR /app\nCOPY Package.swift Package.resolved ./\nRUN swift package resolve --cache-path .build/artifacts\nCOPY Sources Sources\nCOPY Tests Tests\nRUN swift build -c release --static-swift-stdlib\n\n# المرحلة 2: وقت تشغيل مصغر\nFROM ubuntu:22.04\nRUN apt-get update && apt-get install -y libicu70 libxml2 ca-certificates && rm -rf /var/lib/apt/lists/*\nWORKDIR /app\nCOPY --from=builder /app/.build/release/Run .\nEXPOSE 8080\nCMD ["./Run"]\nالنقاط الرئيسية:
\n- \n
- التخزين المؤقت للتبعيات - نسخ
Package.swiftوPackage.resolvedقبل نسخ المصادر. يقوم Docker بتخزين الطبقة مؤقتاً، وعند تغيير الكود فقط، يتم إعادة بناء الثنائيات فقط. \n - العلامة
--static-swift-stdlib- الربط الثابت للمكتبة القياسية لـ Swift. هذا يقلل من متطلبات وقت التشغيل، لكنه يزيد حجم الثنائي بنسبة ~30%. \n - صورة مصغرة - استخدام Ubuntu مع مكتبات النظام الضرورية (
libicu,libxml2). الصورة النهائية أقل من 150 ميجابايت مقارنة بـ 2 جيجابايت في البناء أحادي المرحلة. \n
2. التخزين المؤقت القوي عبر BuildKit ووكلاء SSH
\nعند العمل في CI/CD (GitHub Actions, GitLab CI)، يقوم كل تشغيل بتنزيل التبعيات من جديد. استخدم Docker BuildKit لتركيب ذاكرة التخزين المؤقت لـ Swift PM.
\nDockerfile مع التخزين المؤقت لـ BuildKit
\n# syntax=docker/dockerfile:1\nFROM swift:5.10 AS builder\nWORKDIR /app\nRUN --mount=type=cache,target=/app/.build/artifacts \\\n --mount=type=bind,source=Package.swift,target=Package.swift \\\n --mount=type=bind,source=Package.resolved,target=Package.resolved \\\n swift package resolve\nCOPY Sources Sources\nRUN --mount=type=cache,target=/app/.build/artifacts \\\n swift build -c release --static-swift-stdlib\nالمزايا:
\n- \n
- ذاكرة تخزين مؤقت دائمة - يتم حفظ القطع الأثرية للتبعيات بين عمليات البناء على نفس المضيف. \n
- وكلاء SSH - إذا كان
Package.swiftالخاص بك يشير إلى مستودعات خاصة، استخدم--mount=type=sshللمصادقة دون تخزين المفاتيح في الصورة. \n
بالنسبة لمضيفات macOS (مثل MacStadium)، تأكد من إضافة --platform linux/amd64، لأن Swift على ARM (M1/M2) يتطلب محاكاة.
3. العمل المتقدم مع Swift Package Manager
\nSwift PM ليس مجرد مدير تبعيات، بل هو أيضاً أداة قوية للاختبار والتحليل البرمجي داخل الحاوية.
\nتشغيل الاختبارات في الحاوية مع دعم تغطية الكود
\nFROM swift:5.10 AS te