Hopp til innhold

دوكير - بناء صورة باستخدام ملف Dockerfile

Skip to content

هذا نص مترجم آليًا وقد يحتوي على أخطاء!

بناء صورة باستخدام ملف Dockerfile

هنا تقوم ببناء صورة من تطبيق Flask وتجربتها مع الأمر docker run. تكون قد أكملت المهمة عندما يستجيب التطبيق وتتحقق من أن الملف المحلي .env يبقى خارج الصورة الجديدة. لا يتطلب التطبيق الاختباري استخدام GitHub أو واجهة برمجة تطبيقات خارجية (API).

قبل أن تبدأ البناء

يجب عليك بناء صورة (image) وإظهار أن حاوية من هذه الصورة تستجيب. تحتاج إلى التثبيت Docker والقدرة على تشغيل واستكشاف حاوية، كما هو موضح في استخدام الحاويات Level 1 - تشغيل وفحص حاوية. إذا لم يكن لديك تطبيق Flask، استخدم التطبيق التجريبي أدناه. اعمل في مجلد المشروع داخل آلة افتراضية Linux، حيث توجد ملفات app.py وأي قوالب وملفات مشروع أخرى موجودة.

إذا كان المشروع موجودًا في مستودع أكواد، يوضح Git في الطرفية Level 1 - استنساخ وcommit ودفع كيفية استنساحه إلى الآلة الافتراضية. يمكنك أيضًا إنشاء الملفات في محرر النصوص الخاص بالآلة الافتراضية. استخدم أوامر pwd وls للتأكد من أنك تقف في المجلد الصحيح. لا تبني من مجلد فارغ أو من Shell مضيف Proxmox.

جرّب أولاً باستخدام تطبيق اختبار صغير

إذا لم تقم بعد بنقل التطبيق الخاص بك إلى آلة الافتراضية، يمكنك التدرب على ملف Dockerfile مع تطبيق بسيط للغاية. أنشئ مجلدًا باستخدام mkdir min-app و cd min-app، وأنشئ app.py باستخدام nano:

from flask import Flask
app = Flask(__name__)

@app.route("/")
def index():
    return "مرحباً من الحاوية!"

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)

ثم أنشئ requirements.txt و Dockerfile كما هو موضح أدناه. عندما يعمل البناء، قم بنفس الشيء لتطبيقك الخاص.

أنشئ ملف requirements.txt في نفس المجلد. يُدرج هذا الملف حزم بايثون التي يجب تثبيتها داخل الصورة. بالنسبة للتطبيق البسيط من Flask 1، والذي يستخدم فقط Flask، يكون المحتوى كالتالي:

Flask

إذا كانت التطبيق يستخدم مكتبات طرف ثالث أخرى، يجب أن تكون مدرجة هناك بأسماء الحزم الصحيحة، على سبيل المثال requests. لا يتم نسخ الملفات مثل .venv لتثبيت الحزم؛ حيث يقوم Docker بتثبيتها من جديد من هذه القائمة. يمكن تثبيت الإصدارات، على سبيل المثال باستخدام اسم_الحزمة==الإصدار، بعد التحقق مما هي إصدارات الحزم التي تستخدمها التطبيق.

أنشئ أيضًا ملف .dockerignore قبل أول بناء. يمنع هذا الملف نقل الأسرار المحلية وسجل Git والبيئة المحلية لـPython إلى الصورة:

.env
.git
__pycache__/
.venv/
app-data/

أضِف أيضًا ملف .env إلى قائمة التجاهل في .gitignore إذا كنت تستخدم Git. وإذا كانت ملفات التجاهل تحتوي على محتوى مسبق، أضف القواعد الناقصة بدلاً من استبدال الملفات. استخدم مقال [المستوى الخامس لـ Git في الطرفية - .gitignore والأسرار] للتحقق من التتبع قبل مشاركة الكود.

إنشاء صورة باستخدام Dockerfile

يُستخدم ملف Dockerfile والكود المصدري لبناء الصورة. ثم يتم إنشاء حاوية من هذه الصورة وتشغيلها.

يقوم الأمر docker build بإنشاء الحزمة. يقوم الأمر docker run بإنشاء حاوية من الحزمة وتشغيلها. عملية البناء وحدها لا تُشغّل التطبيق. راجع [[مستوى Docker 0 - ما هو Docker|المستوى 0]] إذا كنت بحاجة إلى التمييز مرة أخرى بين الصورة والحاوية.

تصف [ملف Dockerfile](https://docs.docker.com/reference/dockerfile/) الخطوات التي سيعتمدها Docker لبناء الصورة. كل سطر يؤدي وظيفة محددة:

FROM python:3.12-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .
EXPOSE 5000
CMD ["python", "app.py"]

تنفّذ Docker البناء خطوة بخطوة. يمكن لـ COPY و RUN إضافة طبقات نظام ملفات، بينما يصف أمر مثل CMD كيفية بدء تشغيل الحاوية. يستطيع Docker إعادة استخدام نتائج بناء سابقة من ذاكرة تخزين مؤقت للبناء (build cache). عندما يجب إعادة بناء خطوة معينة، يجب أيضًا تنفيذ الخطوات اللاحقة مرة أخرى.

لذلك ننسخ ملف requirements.txt بمفرده قبل الأمر COPY . .: حيث تأتي عملية التثبيت التي تستغرق وقتًا طويلاً قبل الكود المصدري، الذي يتغير بشكل متكرر:

flowchart TB
    L1["صورة الأساس: python:3.12-slim"] --> L2["مجلد العمل: /app"]
    L2 --> L3["نسخ ملف requirements.txt"]
    L3 --> L4["تثبيت الحزم باستخدام pip"]
    L4 --> L5["نسخ الكود المصدري"]

The input does not contain any comments (lines starting with #) that need translation; it consists solely of executable commands within a Dockerfile code block. Therefore, no changes are made to the content.

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .

إذا تم تعديل ملف requirements.txt، يجب على Docker إعادة تثبيت الحزم. وهذا أمر مرغوب فيه؛ حيث أن الحزمة الجديدة ستُضمَّن فعليًا في الصورة (image). أما إذا كان التعديل يقتصر على الكود المصدري فقط، فإن بإمكان Docker استخدام طبقة التثبيت الجاهزة والمتابعة من الأمر COPY . ..

عندما يقوم Docker بنشر منفذ (publiserer en port)، يُعيد توجيه حركة المرور إلى البرنامج الموجود داخل الحاوية (container). لذلك، يجب على البرنامج الاستماع لشبكة الحاوية وليس فقط على عنوان 127.0.0.1 الذي يعني “هذه الحاوية نفسها”. فإذا استمع البرنامج فقط على 127.0.0.1، فلن تتمكن الأجهزة الأخرى من الوصول إليه عبر منفذ Docker.

مثال على Flask

يجب أن يستمع Flask إلى جميع واجهات الشبكة (0.0.0.0) عند تشغيله داخل حاوية. يعني 0.0.0.0 أن Flask يقبل الطلبات عبر جميع بطاقات الشبكات داخل الحاوية. استبدل كتلة الإقلاع الموجودة في app.py بما يلي:

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000, debug=False)

هذا إعداد للتدريب باستخدام خادم تطوير Flask. قبل استخدام الحل في بيئة الإنتاج، يجب تشغيله على خادم WSGI مناسب؛ راجع Flask: إعدادات الإنتاج.

يصف EXPOSE 5000 المنفذ الذي تستخدمه التطبيق؛ لكنه لا ينشر منفذاً بذاته. يقوم بذلك خيار -p 127.0.0.1:5000:5000 في الأمر أدناه. ابنِ وابدأ التشغيل:

docker build -t min-app:latest .
docker run -d --name min-app -p 127.0.0.1:5000:5000 min-app:latest
docker logs -f min-app

اضغط على Ctrl+C لإنهاء عرض السجلات. تستمر الحاوية في التشغيل.

اختبار من جهاز الظل نفسه:

curl http://127.0.0.1:5000

ستحصل على المحتوى من المسار الرئيسي للتطبيق. في -p 127.0.0.1:5000:5000 تعني 127.0.0.1:5000 المنفذ 5000 على الخادم، ولكن فقط للبرامج الموجودة على الخادم نفسه. الرقم الأخير هو المنفذ داخل الحاوية. إذا لم يعمل الأمر، تحقق أولاً من docker ps والسجلات ومن أن المنفذ منشور بشكل صحيح.

عند استخدام 127.0.0.1 في البداية، يكون المنفذ مغلقًا أمام الشبكة، مما يعني أنه لا يمكن لأي أجهزة أخرى الوصول إلى التطبيق أثناء البناء والاختبار. هذا معيار آمن لتطبيق قيد التطوير. بدون 127.0.0.1 (أي -p 5000:5000) يستمع المنفذ على جميع بطاقات الشبكة للخادم. لن تحتاج إلى ذلك إلا عندما يجب على جهاز آخر أو وكيل وصول إلى التطبيق، كما هو موضح في المستوى الثالث.

نقطة التحقق: يعمل الصورة المخصصة

يجب أن يعرض الأمر curl http://127.0.0.1:5000 الصفحة الرئيسية للتطبيق. بالنسبة لتطبيق الاختبار، تكون الاستجابة هي Hei fra containeren!. اشرح ما بناه أمر docker build وما الذي أطلقه أمر docker run. في حالة وجود خطأ، اقرأ السجل قبل المتابعة.

تحقق من أن ملف ‎.env يبقى خارجًا

لا تحتاج إلى مفتاح حقيقي للتحقق من هذا الأمر. إذا لم يكن لدى المشروع ملف ‎‎.env بالفعل، يمكنك إنشاؤه باستخدام PIGGY_TEST=قيمة_اختبار_آمنة. احتفظ بالملف الموجود؛ لا تكتب فوق قيمك.

  1. تأكد من وجود ‎.env في كلٍّ من ‎.dockerignore و‏‎.gitignore.
  2. إذا كنت تستخدم Git، نفّذ عمليات التحقق الموجودة في [‏[تمرين .gitignore|التمرين الخاص بـ .gitignore في مستوى 5]] (ملاحظة: تم الحفاظ على البنية الأصلية للرابط كما هو). يجب ألا يكون الملف المُتجاهل مضبوطًا مسبقًا أيضًا.
  3. ابنِ الصورة مرة أخرى وتحقّق من مسار هذه الملفات دون طباعة المحتوى:
# docker build -t min-app:latest .
# docker run --rm --entrypoint sh min-app:latest -c 'test ! -e /app/.env && echo "ملف .env غير موجود في /app"'

النتيجة المتوقعة هي ملف .env غير موجود في /app. إذا لم تظهر الرسالة، تحقق من ملف التجاهل قبل مشاركة الصورة (image). يتحكم هذا الأمر في مسار الملف داخل نظام الملفات النهائي للصورة الجديدة. لا يحدّث الصور القديمة أو ملفات الأسرار الأخرى أو القيم المكتوبة مباشرةً في الكود أو ملف Dockerfile. استبدل المفتاح الفعلي أولاً إذا كان قد تم مشاركته سابقًا.

إذا فشلت عملية البناء أو التطبيق

عند ظهور خطأ ModuleNotFoundError، تحقق من ملف requirements.txt وأعد بناء المشروع. في حال حدوث أخطاء أثناء تنزيل الصورة الأساسية أو حزم بايثون (Python)، اختبر الشبكة باستخدام [[طريقة استكشاف الأخطاء وإصلاحها المستوى 1 - الاستكشاف المنهجي للأخطاء|طريقة استكشاف الأخطاء وإصلاحها]]. عند عدم وجود استجابة عبر بروتوكول HTTP، اقرأ سجلات docker logs min-app وتحقق من عنوان خادم فلاكس (Flask) وربط المنافذ.

الخطوات التالية

اعرض إجابة التطبيق والتحقق من .env. اشرح ما يصفه Dockerfile، وما ينشئه البناء، وما الذي يبدأ به docker run. تابع إلى Docker - نشر التطبيق. إذا كنت ترغب في وصف الإقلاع والتحديث في ملف Compose، فإن تشغيل وتحديث التطبيق باستخدام Compose هي تعميق اختياري.



Compose والتحديث موجودان الآن على تشغيل وتحديث التطبيق باستخدام Compose.


التخزين موضح في حفظ البيانات خارج الحاوية; تطبيق Compose موجود على تشغيل وتحديث التطبيق باستخدام Compose.


وصف API موجود الآن على متغير بيئة ومفتاح API وهو اختياري.