Docker وRust: حاويات التطبيقات للإنتاج

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة: لماذا يحتاج مطور Rust إلى Docker؟

تشتهر Rust بأدائها العالي وأمان الذاكرة، ولكن حتى الملف الثنائي الأكثر كفاءة يحتاج إلى بيئة مناسبة للتشغيل. يحل Docker هذه المشكلة عن طريق تغليف التطبيق مع جميع التبعيات في حاوية معزولة. في هذه المقالة، سنشرح كيفية حاوِنة تطبيقات Rust باستخدام Docker، مع استخدام التقنيات الحديثة، بما في ذلك البناء متعدد المراحل وتقليل حجم الصورة.

تعتبر حاوِنة مشاريع Rust مفيدة بشكل خاص لأن Rust يتم تجميعها إلى ملف ثنائي ثابت - وهذا يسمح بإنشاء صور صغيرة (alpine أو حتى scratch) يتم تشغيلها بشكل أسرع وأكثر أمانًا من نظيراتها في Python أو Node.js.



1. الأساسيات: Dockerfile لتطبيق Rust بسيط

سنبدأ بخادم ويب بسيط بلغة Rust باستخدام إطار العمل actix-web. سنقوم بإنشاء Dockerfile أساسي.



1.1. هيكل المشروع

my_rust_app/├── Cargo.toml├── Cargo.lock└── src/    └── main.rs


1.2. مثال على الكود (main.rs)

use actix_web::{get, App, HttpResponse, HttpServer, Responder};

#[get("/")]async fn hello() -> impl Responder { HttpResponse::Ok().body("مرحبًا من حاوية Rust!")}

#[actix_web::main]async fn main() -> std::io::Result<()> { HttpServer::new(|| App::new().service(hello)) .bind("0.0.0.0:8080")? .run() .await}


1.3. Dockerfile بسيط

FROM rust:1.77 AS builderWORKDIR /appCOPY Cargo.toml Cargo.lock ./RUN mkdir src && echo "fn main() {}" > src/main.rsRUN cargo build --releaseCOPY src/ src/RUN cargo build --release

FROM debian:bookworm-slimCOPY --from=builder /app/target/release/my_rust_app /usr/local/bin/EXPOSE 8080CMD ["my_rust_app"]

الشرح: المرحلة الأولى (builder) تقوم بتجميع التطبيق، والمرحلة الثانية تنسخ فقط الملف الثنائي إلى صورة Debian نظيفة. هذا يقلل الحجم من ~2 جيجابايت إلى ~100 ميجابايت.



2. البناء متعدد المراحل: تحسين حجم الصورة

البناء متعدد المراحل (multi-stage build) هو تقنية أساسية لـ Rust. إنها تسمح بفصل بيئة البناء (مع المترجم والتبعيات) عن بيئة التشغيل.



2.1. Dockerfile متقدم مع التخزين المؤقت

لتسريع عمليات البناء المتكررة، نقوم بتخزين التبعيات مؤقتًا:

FROM rust:1.77 AS builderWORKDIR /appCOPY Cargo.toml Cargo.lock ./RUN mkdir src && echo "fn main() {}" > src/main.rsRUN cargo build --release 2>/dev/null || trueCOPY src/ src/RUN cargo build --release && \    cp target/release/my_rust_app /app/rust_app

FROM gcr.io/distroless/cc-debian12COPY --from=builder /app/rust_app /app/rust_appEXPOSE 8080CMD ["/app/rust_app"]

لماذا distroless؟ صورة distroless تحتوي فقط على glibc والمكتبات الأساسية - بدون shell أو apt أو ls. هذا يعزز الأمان ويقلل الحجم إلى ~30 ميجابايت.



2.2. صورة صغيرة على scratch

إذا كان تطبيقك لا يستخدم libc (على سبيل المثال، مكتوب مع #![no_std])، يمكنك استخدام scratch:

FROM rust:1.77 AS builderWORKDIR /appCOPY . .RUN cargo build --release

FROM scratchCOPY --from=builder /app/target/release/my_rust_app /appEXPOSE 8080CMD ["/app"]

هذه الصورة تزن أقل من 10 ميجابايت!



3. Docker Compose: تطبيق متعدد الحاويات

غالبًا ما يعمل تطبيق Rust مع PostgreSQL أو Redis أو Nginx. نستخدم docker-compose.yml:



3.1. مثال على docker-compose.yml

version: '3.8'services:  app:    build: .    ports:      - "8080:8080"    environment:      - DATABASE_URL=postgres://user:pass@db:5432/mydb      - RUST_LOG=info    depends_on:      - db

db: image: postgres:16-alpine ```

المدونات

توصيات الكتب