Docker وC++: حاويات التطبيقات المتقدمة

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

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

ابدأ الدورة

Docker و C++: حاويات التطبيقات على مستوى متقدم



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



نفترض أنك بالفعل على دراية بأساسيات Docker (أوامر docker build، docker run) والصيغة الأساسية لـ Dockerfile. الآن سننتقل إلى المهام الحقيقية: البناء متعدد المراحل، التعامل مع التبعيات النظامية، التصحيح داخل الحاوية، والتكامل مع CI/CD.



1. البناء متعدد المراحل: فصل التجميع عن التنفيذ



المشكلة الرئيسية لـ C++ في Docker هي حجم الصورة. مجموعة الأدوات الكاملة (g++، cmake، make، حزم التطوير) قد تزن 1-2 جيجابايت. الحل هو البناء متعدد المراحل (multi-stage build).



لننظر إلى مثال كلاسيكي: تطبيق C++ يستخدم مكتبة libcurl.



# المرحلة الأولى: البناءFROM ubuntu:22.04 AS builder

RUN apt-get update && apt-get install -y \ build-essential \ cmake \ libcurl4-openssl-dev \ && rm -rf /var/lib/apt/lists/*

WORKDIR /appCOPY . .

RUN cmake -B build -DCMAKE_BUILD_TYPE=Release \ && cmake --build build --parallel $(nproc)

# المرحلة الثانية: صورة التنفيذFROM ubuntu:22.04-slim

RUN apt-get update && apt-get install -y \ libcurl4 \ && rm -rf /var/lib/apt/lists/*

COPY --from=builder /app/build/myapp /usr/local/bin/myapp

CMD ["myapp"]


النقاط الرئيسية:

  • في المرحلة الأولى (builder) نقوم بتثبيت جميع الأدوات والتبعيات اللازمة للبناء.
  • في المرحلة الثانية - فقط تبعيات وقت التشغيل (libcurl4 بدلاً من libcurl4-openssl-dev).
  • الصورة النهائية تحتوي فقط على الملف الثنائي المترجم والمكتبات الضرورية.
  • نستخدم --parallel $(nproc) لتسريع البناء.


ينخفض حجم الصورة من ~1.2 جيجابايت إلى ~80 ميجابايت. هذا أمر بالغ الأهمية للنشر وتنزيل الصور في CI/CD.



2. تحسين التخزين المؤقت وطبقات Docker



كل تعليمة في Dockerfile تنشئ طبقة. الترتيب الخاطئ للتعليمات يؤدي إلى إعادة تعيين ذاكرة التخزين المؤقت بالكامل عند أدنى تغيير في الكود.



القاعدة: أولاً ننسخ ما يتغير نادراً (CMakeLists.txt، التبعيات)، ثم الكود.



FROM ubuntu:22.04 AS builder

WORKDIR /app

# 1. التبعيات النظامية (تتغير نادراً)RUN apt-get update && apt-get install -y \ build-essential cmake libboost-all-dev \ && rm -rf /var/lib/apt/lists/*

# 2. ملفات تكوين البناء (تتغير بشكل غير متكرر)COPY CMakeLists.txt .

# 3. الكود المصدري (يتغير باستمرار)COPY src/ ./src/

# 4. البناءRUN cmake -B build && cmake --build build


نصائح إضافية:

  • استخدم .dockerignore لاستبعاد build/، .git/، *.o.
  • قم بتجميع RUN apt-get install في أمر واحد - فهذا يقلل عدد الطبقات.
  • لمشاريع C++ التي تحتوي على عدد كبير من ملفات الرأس، فكر في استخدام ccache داخل الحاوية.


3. التعامل مع المكتبات النظامية والربط الثابت



أحياناً تكون المكتبات الديناميكية في الحاوية مفقودة أو غير متوافقة. النهج المتقدم هو الربط الثابت أو استخدام Alpine Linux.



الخيار A: البناء الثابت (g++)

FROM alpine:3.18 AS builder

RUN apk add --no-cache g++ gcc musl-dev make cmake

WORKDIR /appCOPY . .

# الربط الثابتRUN g++ -static -O2 -o myapp main.cpp -lpthread

FROM scratchCO

المدونات

توصيات الكتب