لماذا Rust وDocker زوج مثالي؟
\n\nتخيل: لقد كتبت تطبيقًا فائق السرعة بلغة Rust يعالج ملايين الطلبات في الثانية. يتم تجميعه في ملف ثنائي ثابت، ولا يتطلب آلة افتراضية، ويعمل أسرع من C++ في بعض السيناريوهات. ولكن كيف تنقل هذه الأعجوبة الهندسية إلى الخادم؟ كيف تضمن أنها ستعمل بنفس الطريقة على جهاز المطور المحلي، وفي CI/CD، وفي الإنتاج؟
\n\nالإجابة بسيطة — حاويات تطبيقات Rust باستخدام Docker. يتيح لك Docker حزم تطبيقك مع جميع التبعيات في حاوية خفيفة الوزن. وRust، بفضل طبيعتها، تجعل هذه العملية فعالة بشكل لا يصدق. في هذه المقالة، لن نكتب Dockerfile فحسب — بل سنحول ملفك الثنائي إلى عمل فني في عالم الحاويات.
\n\nإذا كنت بالفعل على دراية بـ التطوير بلغة Rust، ولكنك ترغب في إتقان DevOps لمشاريع Rust — فأنت في المكان الصحيح. هيا بنا!
\n\nمشكلة Dockerfile "الساذج" لـ Rust
\n\nغالبًا ما يكتب المبتدئون شيئًا كهذا:
\n\nFROM rust:latest\nWORKDIR /app\nCOPY . .\nRUN cargo build --release\nCMD ["./target/release/my_app"]\n\nهذا يعمل. لكن دعونا نواجه الحقيقة: هذا النهج يشبه قيادة سيارة فيراري على طريق وعِر. لماذا؟
\n\n- \n
- حجم صورة ضخم — حوالي 1.5 جيجابايت بسبب المترجم وأدوات البناء \n
- إعادة بناء بطيئة — لا يتم استخدام ذاكرة التخزين المؤقت للتبعيات \n
- ثغرات أمنية — الصورة تحتوي على الكثير من الحزم غير الضرورية \n
- انتهاك أفضل الممارسات — يجب ألا يحتوي وقت التشغيل على مترجم \n
تتطلب حاويات تطبيقات Rust الحقيقية نهجًا أكثر ذكاءً. واسمه — البناء متعدد المراحل (multi-stage build).
\n\nحاويات Rust الصحيحة: البناء متعدد المراحل
\n\nالفكرة بسيطة: المرحلة الأولى — "السقالات البنائية" حيث يعيش المترجم. الثانية — "وقت تشغيل" نظيف، حيث يصل فقط الملف الثنائي النهائي. دعونا ننفذ هذا عمليًا.
\n\nالخطوة 1: Dockerfile أساسي
\n\nلننشئ ملف Dockerfile في جذر مشروع Rust الخاص بك (بجانب Cargo.toml):
# ====================\n# المرحلة 1: البناء\n# ====================\nFROM rust:1.77-slim-bookworm AS builder\n\n# إنشاء مشروع فارغ لتخزين التبعيات مؤقتًا\nRUN USER=root cargo new /app\nWORKDIR /app\n\n# نسخ ملفات البيان فقط (لتخزين الطبقات مؤقتًا)\nCOPY Cargo.toml Cargo.lock ./\n\n# بناء التبعيات (هذه الطبقة تُخزَّن مؤقتًا إذا لم يتغير Cargo.toml)\nRUN cargo build --release 2>/dev/null || true\n\n# الآن ننسخ الكود المصدري\nCOPY src ./src\n\n# بناء التطبيق (فقط الملفات التي تغيرت)\nRUN cargo build --release\n\n# ====================\n# المرحلة 2: صورة مصغرة\n# ====================\nFROM debian:bookworm-slim AS runtime\n\n# تثبيت التبعيات الدنيا (إذا لزم الأمر)\n# RUN apt-get update && apt-get install -y ca-certificates tzdata && rm -rf /var/lib/apt/lists/*\n\n# نسخ الملف الثنائي من builder\nCOPY --from=builder /app/target/release/my_app /usr/local/bin/my_app\n\n# إعدادات الإنتاج\nENV RUST_LOG=info\nENV APP_ENV=production\n\n# التشغيل من مستخدم غير مميز\nRUN useradd -m -u 1000 appuser\nUSER appuser\n\nEXPOSE 8080\nCMD ["my_app"]\n\nلاحظ السحر مع COPY Cargo.toml Cargo.lock ./ و cargo build قبل نسخ الكود المصدري. هذه هي الحيلة الأساسية لـ تحسين بناء Docker لـ Rust: Docker يخزن الطبقات مؤقتًا، وطالما لم تغير التبعيات، لن يتم إعادة بناء هذه المرحلة. توفير الوقت — من 5 إلى 15 دقيقة لكل بناء!
الخطوة 2: استخدام Alpine (تخفيف شديد)
\n\nإذا كنت ترغب في الحصول على صورة بحجم أقل من 10 ميجابايت، استخدم alpine:
# مرحلة البناء تبقى كما هي\n\n# المرحلة 2: Alpine\nF