5.3 · Docker لبايثون (Python)

المستوى 5 · المستوى الاحترافي والتصنيع (industrialization)

5.3Docker لبايثون (Python)

الهدف: تغليف تطبيق بايثون (وب/بيانات) بحاوية مع Docker.
الوقت المقدّر: 15 دقيقة · قراءة ذاتية · إذا كان لديك 5 دقائق فقط: اقرأ «الأساسي في 30 ثانية» + المخطط.

الأساسي في 30 ثانية

  • انتهى « يشتغل على جهازي » : تحمل الحاوية التطبيق مع بيئته وتدور بالمطابقة في كل مكان.
  • الاعتمادات قبل الشيفرة : قاعدة slim، و requirements منسوخة ومثبتة أولا — تبقى الذاكرة المخبأة بعد التعديلات.
  • تطوير مقابل إنتاج : ربط mount + إعادة تحميل في التطوير، وشيفرة منسوخة + عمال (workers) في الإنتاج — نفس الصورة أساسا.

حالة مصغرة متسلسلة — نبيل يغلف بالحاويات في الجزائر

يعمل خط نبيل غير المتزامن تماما في الجزائر — لكنه يتعطل عند زميلته (إصدار بايثون مختلف، واعتمادات ناقصة، ومنفذ لا يُوصَل). كتب Dockerfile : قاعدة slim، و requirements مثبتة قبل الشيفرة، ومستعمل غير جذري، وإطلاق على كل الواجهات. ثم Compose مع قاعدة البيانات. تتمة الحالات 5.1-5.2 — جعل نبيل تحليله محمولا.

تتمة الحالات 5.1-5.2 — مر نبيل من « عندي يشتغل » إلى « في كل مكان نفسه ».

1. Dockerfile بايثون الذي يشتغل

يغلف Docker تطبيق بايثون مع بيئته الكاملة (إصدار بايثون، والاعتمادات، والنظام) في حاوية (conteneur) تُنفَّذ بالمطابقة في كل مكان. الوصفة (Dockerfile) : قاعدة python:3.12-slim، وCOPY requirements.txt ثم pip install قبل الشيفرة (تبقى ذاكرة البناء المخبأة بعد التعديلات)، وUSER غير جذري، وCMD يطلق. ويستبعد .dockerignore الـ .venv و__pycache__ و.git : ينحف السياق، ويسرع البناء. لم يعد نبيل يتناقش في الإصدارات : تسافر البيئة مع الشيفرة.

منعكس : كل ما يعيش على جهازكم وينقص في الصورة هو تعطل مستقبلي في مكان آخر — يجب أن تحوي الصورة كل شيء، والاعتمادات ضمنا.

2. تطوير مقابل إنتاج : وجهان

نفس الصورة أساسا، وإطلاقان. في التطوير : ربط (bind mount) للشيفرة + --reload (FastAPI/Flask) — نعدل، فيعيد التحميل دون إعادة بناء. في الإنتاج : شيفرة منسوخة في الصورة، وخادم gunicorn/uvicorn متعدد العمال، وإعداد بمتغيرات -e، واستماع على 0.0.0.0 (أبدا localhost، غير القابل للوصول في حاوية). يطور نبيل بالربط ويسلم بالنسخ : وجهان، ووصفة واحدة.

للتجنب : خلط الاثنين — إعادة تحميل في الإنتاج، أو شيفرة منسوخة متجمدة في التطوير تفرض إعادة بناء عند كل فاصلة.

3. Compose للتطبيق الكامل

التطبيق الحقيقي عدة حاويات : api (بناء Dockerfile) + bdd (قاعدة + مجلد دائم) على نفس الشبكة، وDATABASE_URL في متغير، وdepends_on + إعادة محاولة عند الإقلاع. يصف Compose كل ذلك ويرفع حزمة محلية مطابقة للتكامل المستمر (CI) بأمر واحد. أضاف نبيل القاعدة إلى Compose : تقلع زميلته في دقائق، بنفس الإصدارات.

يفصل المستوى 3 من دليل Docker كل سطر : هنا، نحتفظ بالحركة — أمر واحد، والحزمة كلها، في كل مكان نفسه.

خطأ شائع في الفهم: « يستبدل Docker الـ venv، ويكفي localhost كمضيف ». خطأ مزدوج. يعزل الـ venv اعتمادات بايثون على جهازكم ؛ ويعزل Docker التطبيق كله (بايثون، ونظام، واعتمادات) في محمول — نستعمل غالبا الاثنين (venv في التطوير، و Docker للتسليم). وفي حاوية، لا يُوصَل إلى localhost إلا من الحاوية نفسها : يجب أن يستمع الخادم على 0.0.0.0.
بايثون مغلف بالحاويات نفس الصورة، من الحاسوب إلى الخادم slim + ذاكرة مخبأة الاعتماداتقبل الشيفرةUSER + .dockerignore غيرجذري، وسياق نحيفCompose (api+bdd) حزمةكاملة بأمر واحد
نفس الصورة، من الحاسوب إلى الخادم
نص المخطط (SEO / قارئات الشاشة / الترجمة): 1) Dockerfile : انطلق نبيل من قاعدة slim في الجزائر، ونسخ requirements ثم ثبت قبل الشيفرة (ذاكرة مخبأة)، واستبعد .venv عبر .dockerignore، وأنشأ USER غير جذري. 2) بناء/تشغيل : تجمد الصورة التطبيق وبيئته، وتستمع الحاوية على 0.0.0.0. 3) Compose : أُطلقت api + bdd معا، و DATABASE_URL في متغير. الدرس : تسافر البيئة مع الشيفرة.

🔎 مثال ملموس — واجهة API نبيل في حاوية

وصفة عامة : slim، وذاكرة مخبأة، وغير جذري، واستماع مفتوح.

FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
RUN useradd -m app && chown -R app:app /app
USER app
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

القراءة : الـ requirements مخفي قبل الشيفرة المتغيرة — تبقى الذاكرة المخبأة بعد الفواصل.

الدرس : --host 0.0.0.0 إجباري في حاوية، أبدا localhost.

مفردات القسم

Docker
أداة تغلف التطبيق وبيئته في حاوية محمولة.

مثال بسيط: يدور تحليل نبيل نفسه في الجزائر وعند زميلته.

ما ليس كذلك: venv مُعاد إنشاؤه يدويا على كل جهاز.

رد فعل: هل ما زال تطبيقي يعتمد على جهازي ؟

الصورة (image)
نموذج مجمد للتطبيق + الاعتمادات، مبني من Dockerfile.

مثال بسيط: يبني نبيل صورة مُصدَرة لكل تسليم.

ما ليس كذلك: الحاوية الجارية التنفيذ.

رد فعل: هل يمكنني إعادة بناء هذه الصورة بالمطابقة ؟

Dockerfile
وصفة البناء : قاعدة slim، واعتمادات، وشيفرة، وإطلاق.

مثال بسيط: وصفة نبيل المقروءة، requirements قبل الشيفرة.

ما ليس كذلك: تثبيت يدوي لبايثون على خادم.

رد فعل: هل الاعتمادات مثبتة قبل الشيفرة ؟

.dockerignore
يستبعد غير النافع من السياق (.venv، والمخابئ، و .git) لتنحيف البناء.

مثال بسيط: استبعد نبيل .venv و __pycache__ : بناء أسرع.

ما ليس كذلك: نسخ .venv في الصورة.

رد فعل: ما الذي يثقل سياقي ؟

Compose
يصف عدة حاويات (api + bdd) مطلقة معا.

مثال بسيط: يرفع نبيل الـ api والقاعدة بأمر واحد.

ما ليس كذلك: حاوية واحدة معزولة دون قاعدة.

رد فعل: هل يقلع الوافد الجديد بأمر واحد ؟

في التطبيق — تغليف تطبيق بايثون بالحاويات

  1. ثبتوا Docker Desktop. وجهزوا تطبيق بايثون صغيرا (مثلا سكريبتا أو واجهة FastAPI) مع requirements.txt الخاص به.
  2. اكتبوا Dockerfile : صورة قاعدة « FROM python:3.12-slim »، ونسخ الشيفرة، و« RUN pip install -r requirements.txt »، وأمر إطلاق (CMD).
  3. ابنوا الصورة : « docker build -t mon-app . »، ثم أطلقوا حاوية : « docker run mon-app » (مع -p لكشف منفذ إن كانت واجهة API).
  4. عدلوا الشيفرة، وأعيدوا البناء وأعيدوا الإطلاق : قيسوا قابلية إعادة الإنتاج — تدور الحاوية بالمطابقة في كل مكان.
تغلفون تطبيق بايثون مع Dockerfile وتطلقونه في حاوية : مفتاح نشر موثوق ومحمول.

نص جاهز للقول — اقتراح Docker على الفريق

« يعمل تحليلنا على جهازي في الجزائر لكن لا يعمل في مكان آخر : إنه مشكل بيئة، لا شيفرة — إصدار بايثون، واعتمادات. أقترح Dockerfile نحيفا مع requirements مثبتة قبل الشيفرة، و USER غير جذري، مع Compose مع القاعدة. سيطلق كل واحد نفس الصورة، وتبقى الأسرار خارج الصورة، في متغيرات البيئة. »

يُقال في الاجتماع لاعتماد التغليف بالحاويات دون استهداف خبرة DevOps.

نموذج نسخ-لصق — Dockerfile بايثون + Compose عامان

FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
RUN useradd -m app && chown -R app:app /app
USER app
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
# --- docker-compose.yml (حزمة عامة) ---
# services:
#   api:
#     build: .
#     ports: ["8000:8000"]
#     environment:
#       - DATABASE_URL=postgresql://db:5432/app
#   db:
#     image: postgres:16
#     volumes: ["pgdata:/var/lib/postgresql/data"]

مستقل / ميزانية صغيرة

نبيل وحده : يكفي Dockerfile نحيف دون Compose — تجمد الصورة أصلا بايثون والاعتمادات.

مقاولة صغيرة / فريق مصغر

Compose للـ api + bdd : يقلع كل زميل الحزمة الكاملة دون تثبيت بايثون ولا القاعدة.

مقاولة متوسطة في الجزائر

يتقاسم نبيل الصورة في الجزائر : يختبر الجميع نفس الإصدار، وانتهت فروق الأجهزة.

فريق يبدأ

ثنائي : أحدهما يكتب Dockerfile، والآخر يتحقق من USER و .dockerignore و 0.0.0.0 قبل الاعتماد.

حذر: لا تضعوا أبدا أسرارا (كلمات سر، مفاتيح، رموز) في Dockerfile ولا في الصورة : مرروها عبر البيئة عند الإطلاق. الصورة المتقاسمة تحتفظ بكل محتواها — يبقى السر المدمج فيها مقروءا.

✓ ممارسات جيدة

  • slim + ذاكرة مخبأة : الـ requirements أولا، والشيفرة بعد.
  • USER غير جذري منهجيا ؛ و .dockerignore ضد .venv والمخابئ.
  • 0.0.0.0 في حاوية، أبدا localhost.

✗ أخطاء شائعة

  • نسخ .venv في الصورة (ثقيلة، غير محمولة).
  • الاستماع على localhost : تبقى الخدمة غير قابلة للوصول.
  • خلط التطوير (ربط + إعادة تحميل) والإنتاج (منسوخ + عمال).

النقاط الأساسية

  • يغلف Docker التطبيق + بيئته : انتهى « يشتغل على جهازي ».
  • الصورة = نموذج مجمد ؛ والحاوية = نسخة جارية التنفيذ.
  • يصف Dockerfile وصفة بناء الصورة.
  • بناء (build) ثم تشغيل (run) : دورة Docker الأساسية.

تحدي 48 ساعة — طبق غدا

اكتبوا Dockerfile تطبيقكم (النموذج أعلاه) وأطلقوه في حاوية : هل يجيب نفسه كما على جهازكم ؟

قائمة الخروج من القسم
  • أستطيع شرح صورة مقابل حاوية في جملة واحدة.
  • يبني Dockerfile عندي صورة تدور.
  • أعرف لماذا لا تظهر الأسرار فيها.
تقييم ذاتي 1-5 : هل صورتي قابلة لإعادة البناء بالمطابقة ؟هل سيقلع زميل حزمتي بأمر واحد ؟

أسئلة شائعة

هل يستبدل Docker البيئات الافتراضية (venv) ؟

يعملان في مستويين مختلفين. يعزل venv اعتمادات بايثون لمشروع على جهازكم. ويعزل Docker التطبيق كله (بايثون، ونظام، واعتمادات) في حاوية محمولة. عمليا، نستعمل غالبا venv في التطوير وDocker للتسليم/النشر — متكاملان، لا متنافسان.

هل Docker ضروري لمبتدئ ؟

لا لتعلم اللغة. لكن حالما ننشر تطبيقا حقيقيا، ونعمل جماعة أو نستهدف السحابة، يصبح Docker معيارا شبه لا مفر منه. إنها مهارة مقدرة جدا : تناوله في المستوى الاحترافي هو الوقت الصحيح.

تحقّق من فهمك

أي مشكل يحل Docker أساسا ؟

موارد إضافية (اختياري، للتعمّق أكثر)

اختبار المستوى 5أسئلة جديدة وأصعب للتحقق من مكتسباتك