كتابة أول Dockerfile: تحويل سكربت Python إلى صورة (Image) معزولة
كتابة أول Dockerfile: تحويل سكربت Python إلى صورة Image معزولة
أحد أكثر الأسباب شيوعاً لفشل النشر بين بيئة المطور والسيرفر هو اختلاف الاعتماديات وإصدارات النظام. هنا تظهر قيمة Containerization بوصفها طبقة عزل عملية تجعل التطبيق ينتقل من جهازك إلى أي خادم بنفس السلوك تقريباً.
إذا كنت قد قرأت من قبل مقال مشكلة “الكود يعمل على جهازي فقط” وكيف يحلها Docker نهائياً؟ فهذه الخطوة هي التطبيق العملي المباشر للفكرة. سنحوّل سكربت Python بسيط إلى صورة قابلة للتشغيل على أي خادم يدعم Docker.
هذا النوع من التغليف لا يخدم المطور فقط، بل يسهّل كذلك تصميم أنابيب CI/CD، وتثبيت السلوك التشغيلي داخل بيئات Jenkins وGitHub Actions، ثم نشر الحاوية لاحقاً داخل Kubernetes أو على خادم منفرد.
ما الذي يفعله Dockerfile فعلياً؟
Dockerfile هو ملف وصف بنائي يحدد كيف تُبنى الصورة خطوة بخطوة. بدلاً من إعداد الخادم يدوياً باستخدام أوامر متفرقة، تقوم بكتابة تعليمات تصف النظام الأساسي، الاعتماديات، ملفات التطبيق، وأمر التشغيل النهائي.
بكلمات معمارية أدق، الصورة الناتجة تصبح وحدة نشر موحدة. وهذا يعني أن نفس الصورة يمكن اختبارها في مرحلة Build، ثم تمريرها لمرحلة Test، ثم دفعها إلى السجل، وأخيراً نشرها دون إعادة بناء مختلفة بين البيئات.
- تحديد صورة أساسية مثل
python:3.11-slim - تثبيت الاعتماديات من ملف
requirements.txt - نسخ كود التطبيق داخل بيئة معزولة
- تشغيل السكربت بأمر واضح وقابل للتكرار
هيكل المشروع قبل بناء الصورة
لنفترض أن لديك مشروعاً صغيراً يحتوي على سكربت يطبع رسالة ويعالج بعض القيم. البنية التالية مناسبة لبداية نظيفة، خصوصاً إذا كنت قد أنهيت مسبقاً تثبيت Docker وإعداد بيئة العمل على Linux و Windows.
python-docker-app/
├── app.py
├── requirements.txt
└── Dockerfile
محتوى ملف app.py يمكن أن يكون بسيطاً في البداية:
print("Hello from Python inside Docker!")
أما ملف requirements.txt فسيحمل أي مكتبات خارجية يحتاجها المشروع. إن لم تكن هناك مكتبات الآن، يمكنك تركه فارغاً أو إضافة مكتبة تجريبية لاحقاً.
كتابة أول Dockerfile بشكل هندسي صحيح
الملف التالي ليس مجرد مثال تعليمي، بل نقطة بداية جيدة لتطبيقات Python الصغيرة والمتوسطة. لاحظ أننا نستخدم نسخة slim لتقليل الحجم وتحسين سرعة النقل عبر السجل.
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt /app/
RUN pip install --no-cache-dir -r requirements.txt
COPY . /app/
CMD ["python", "app.py"]
شرح التعليمات سطراً بسطر
FROM: يحدد الصورة الأساسية التي ستبدأ منها عملية البناء.WORKDIR: يضبط مجلد العمل داخل الحاوية، ما يجعل الأوامر التالية أكثر ترتيباً.COPY requirements.txt: ينسخ ملف الاعتماديات أولاً للاستفادة من آليةlayer caching.RUN pip install: يثبت المكتبات داخل الصورة نفسها وليس على جهازك المحلي.COPY . /app/: ينسخ بقية ملفات المشروع.CMD: يحدد الأمر الافتراضي عند تشغيل الحاوية.
بناء الصورة وتشغيل الحاوية
بعد كتابة الملف، انتقل إلى جذر المشروع وابنِ الصورة. إذا كنت ما زلت تتعرف على دورة حياة الصور، فمقال فهم صور دوكر (Docker Images) وكيفية سحبها وإدارتها يشرح المفهوم الذي يحدث الآن في الخلفية.
docker build -t python-script:v1 .
بعد اكتمال البناء، شغّل الحاوية:
docker run --rm python-script:v1
يجب أن ترى الرسالة القادمة من داخل البيئة المعزولة. هذا يعني أن التطبيق يعمل داخل صورة مستقلة عن نظامك المضيف، وأن الاعتماديات أصبحت جزءاً من الحزمة القابلة للنشر.
ولفهم أوامر الإدارة اليومية مثل الإيقاف والفحص والحذف، يمكنك الرجوع إلى أوامر Docker الأساسية للتحكم: تشغيل، إيقاف، فحص، وحذف الحاويات.
أفضل الممارسات لتقليل الحجم وتحسين الأداء
في البيئات الإنتاجية، لا يكفي أن تعمل الصورة فقط. يجب أن تكون خفيفة، آمنة، وقابلة للبناء بسرعة داخل أنابيب CI/CD. كل ميغابايت إضافي يؤثر على زمن السحب والنشر، خاصة في البنى التي تستخدم Auto Scaling أو تحديثات متكررة.
- استخدم صوراً أساسية خفيفة مثل
slimبدلاً من الصور الكاملة عند الإمكان. - انسخ ملف الاعتماديات قبل نسخ المشروع للاستفادة من التخزين المرحلي.
- استخدم
--no-cache-dirمعpipلتفادي بقايا غير ضرورية. - لا تضع ملفات حساسة داخل سياق البناء مثل مفاتيح
SSHأو ملفات الأسرار.
لا تستخدم حساب
rootداخل الحاوية في التطبيقات الإنتاجية إلا لضرورة مدروسة. تشغيل الخدمات بمستخدم محدود الصلاحيات يقلل أثر الاختراق ويمنع كثيراً من سيناريوهات التصعيد الداخلي، خصوصاً عند ربط الحاويات بمجلدات من الخادم أو عند العمل داخل عناقيدKubernetes.
نسخة أكثر احترافية للإنتاج
إذا أردت تحسين الملف السابق، يمكنك إنشاء مستخدم غير جذري وتثبيت بعض الإعدادات التشغيلية الأكثر أماناً. هذا مهم عندما تنتقل من التجارب المحلية إلى بيئات استضافة حقيقية أو إلى منصات تنسيق الحاويات.
FROM python:3.11-slim
WORKDIR /app
RUN useradd -ms /bin/bash appuser
COPY requirements.txt /app/
RUN pip install --no-cache-dir -r requirements.txt
COPY . /app/
RUN chown -R appuser:appuser /app
USER appuser
CMD ["python", "app.py"]
هذا التعديل الصغير يحسن وضع الأمان فوراً، ويجعل الصورة أقرب إلى المعايير التي تتوقعها الفرق المسؤولة عن المنصات والبنية التحتية.
كيف يندمج هذا مع CI/CD والبنية السحابية؟
في المشاريع الحديثة، لا يُبنى Dockerfile فقط لغرض التشغيل المحلي، بل ليكون حجر الأساس لمرحلة النشر المؤتمت. عند كل commit يمكن لخط أنابيب البناء أن ينفذ اختباراتك، يبني الصورة، يوسمها بإصدار واضح، ثم يدفعها إلى سجل مركزي.
بعد ذلك، يمكن لأدوات مثل Terraform تجهيز البنية السحابية، بينما تتولى Ansible أو منصات التنسيق عمليات التهيئة والنشر. هنا يتحول السكربت الصغير إلى مكوّن يمكن تكراره وضبطه ومراجعته ضمن حوكمة هندسية كاملة.
تجنّب استخدام الوسم
latestفي البيئات الحساسة. تثبيت الإصدارات بدقة يمنع الانقطاعات المفاجئة الناتجة عن تغيّر الصورة الأساسية أو تحديث مكتبة بشكل غير متوقع، وهي من أكثر أسبابDowntimeشيوعاً في خطوط النشر المؤتمتة.
أخطاء شائعة عند كتابة أول ملف
- نسخ المشروع كاملاً قبل تثبيت الاعتماديات، ما يضعف كفاءة التخزين المرحلي.
- الخلط بين بيئة الجهاز المحلي وبيئة الحاوية عند قراءة الملفات أو المسارات.
- نسيان ملف
requirements.txtأو عدم تثبيت الإصدارات. - تشغيل الحاوية بنجاح محلياً دون التحقق من سلوكها عند إعادة التشغيل أو داخل خادم نظيف.
وإذا كنت لا تزال في المراحل الأولى من هذه الرحلة، فمقال ما هو DevOps؟ ولماذا تدفع الشركات ثروات لمهندسي الأتمتة السحابية؟ يضع هذا النوع من الأتمتة ضمن الصورة الأكبر لعمل المهندس الحديث.
الخلاصة
كتابة أول Dockerfile ليست مجرد تمرين على أوامر جديدة، بل انتقال حقيقي من تشغيل سكربتات معزولة على جهازك إلى بناء وحدات نشر قابلة للتكرار والاختبار والأتمتة. عندما تحوّل سكربت Python إلى صورة مستقلة، فأنت تبني أساساً تقنياً يمكن توسيعه لاحقاً نحو خدمات ويب، مهام مجدولة، أو تطبيقات مصغرة داخل بنية سحابية متكاملة.
ابدأ بملف بسيط، افهم كل تعليمة فيه، ثم حسّن الصورة تدريجياً من حيث الأمان والحجم وقابلية الدمج مع Pipelines. بهذه الطريقة يصبح Docker أداة هندسية حقيقية، لا مجرد وسيلة تشغيل محلي مؤقتة.
2 comments