العودة إلى المدونة

بناء ونشر تطبيق Flask باستخدام Docker على Ubuntu 20.04

بناء ونشر تطبيق Flask باستخدام Docker على Ubuntu 20.04

مقدمة

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

Flask هو إطار عمل ويب مصغر مفتوح المصدر مبني باستخدام Python. بعض الميزات الرائعة لـ Flask هي أنه خفيف الوزن ومرن ومنظم للغاية. بالإضافة إلى ذلك، لا يتطلب أي أدوات أو إضافات محددة للتشغيل.

يمنحك الجمع بين Flask و Docker تطبيقًا خفيف الوزن ومرنًا وقابلاً للتوسع. يمكنك نشره عبر العديد من الخوادم والبنى التحتية، بفضل الطبيعة المحمولة لحاويات Docker.ينصب تركيز هذا البرنامج التعليمي على توضيح كيفية نشر تطبيق Flask باستخدام Docker. سنوضح أيضًا كيفية التأكد من تفعيل التحديثات المستقبلية لتطبيقك.

المتطلبات الأساسية

سيكون هذا برنامجًا تعليميًا عمليًا، ويجب عليك إنشاء بيئة تمكنك من المتابعة:

الآن، لنبدأ!

الخطوة 1: تحضير تطبيق Flask

سنبدأ بإنشاء دليل يحتوي على تطبيق Flask الخاص بنا. يمكنك تحديد اسم دليل من اختيارك. ومع ذلك، في هذا البرنامج التعليمي، سنطلق عليه اسم flask_demo. سنقوم بحفظ ملفات المشروع داخل دليل /var/www، وهو عادةً الدليل الذي يسمح Ubuntu بالوصول إليه عبر الإنترنت العام افتراضيًا. أولاً، قم بتنفيذ الأوامر التالية لإنشاء الدليل والانتقال إليه:

داخل هذا الدليل الجذري لمشروعنا، سنقوم بإنشاء بنية المجلد الأساسية لتطبيق Flask. بعد ذلك، قم بتنفيذ الأمر التالي لإنشاء البنية الأساسية، مع إضافة العلامة -p لإنشاء جميع المجلدات الأبوية على طول الطريق:

يحتوي مجلد app على جميع الملفات المتعلقة بتطبيق Flask بما في ذلك views و blueprints. تحتوي views على الكود الذي تكتبه للاستجابة للطلبات التي تصل إلى تطبيقك. تساعد blueprints في إنشاء مكونات التطبيق ودعم الأنماط الشائعة في تطبيقات Flask.

مجلد static ذو الاسم المناسب يحتوي على الأصول الثابتة مثل الصور وملفات CSS و JavaScript. بينما يحتوي دليل templates على جميع قوالب HTML الخاصة بالمشروع.

الآن يمكننا البدء في كتابة الملفات اللازمة لتهيئة تطبيق Flask. ابدأ بإنشاء ملف باسم __init__.py داخل دليل app لإخبار Python مفسر بأن دليل app يجب أن يُعامل كحزمة. قم بتنفيذ الأمر التالي على الطرفية لفتح الملف باستخدام محرر nano:

نحن نستخدم الحزم في Python لتجميع الوحدات (modules) في مساحات أسماء أو تسلسلات هرمية منطقية. تتيح البرمجة التركيبية (Modularization) تقسيم الكود إلى كتل فردية وسهلة الإدارة تؤدي وظائف محددة.

بعد ذلك، داخل ملف __init__.py المفتوح في المحرر الخاص بك، أضف مقتطف الكود التالي لبدء مثيل Flask، واستيراد المنطق من views.py الذي ستقوم بإنشائه في الخطوات التالية:

عند الانتهاء، اضغط على Ctrl + O ثم ENTER لحفظ الملف، ثم أغلقه باستخدام Ctrl + X. بعد ذلك، لنقم بإنشاء views.py داخل دليل app . يحتوي ملف views.py على معظم منطق التطبيق:

داخل الملف، أضف مقتطف الكود التالي. سيعرض هذا الكود سلسلة نصية بسيطة لتوضيح أن تطبيقك يعمل عندما يزور المستخدمون موقعك الإلكتروني:

في هذا الملف، نبدأ باستيراد مثيل تطبيق Flask. بعد ذلك، نحتاج إلى إضافة سطر لتحديد المسار: @app.route(/). يُشار إلى سطر @app.route(/) باسم decorator في Flask. يمكنك استخدام الـ decorators لحقن وظائف إضافية في دالة واحدة أو أكثر. في هذه الحالة، نقوم بتمرير استدعاء للمسار / إلى دالة home. عندما يزور المستخدم هذا المسار، سيرى النص: "تطبيق Flask الخاص بنا يعمل!".

بعد ذلك، ستقوم بإنشاء ملف uwsgi.ini للاحتفاظ بتكوينات uWSGI الخاصة بالتطبيق. uWSGI هو خيار نشر لـ Nginx يعمل كبروتوكول وخادم تطبيقات. قم بتشغيل الأمر التالي لإنشاء الملف في الدليل الجذري للمشروع باستخدام محرر nano:

داخل الملف المفتوح، أضف مقتطف الكود التالي:

يحتوي هذا الملف على بعض التوجيهات. نحدد الغرض منها أدناه:

  • module – يحدد الوحدة (module) التي سيتم تقديم تطبيق Flask منها. لقد قمنا بتعيين الوحدة كـ main، مع الإشارة إلى ملف main.py في الدليل الجذري. سنقوم بإنشاء هذا الملف في الخطوة التالية.
  • callable – يوجه uWSGI لاستخدام مثيل app المصدر من التطبيق.
  • master – يضمن استمرار تشغيل التطبيق لتقليل وقت التوقف أثناء إعادة تحميل التطبيق بالكامل.

احفظ الملف وأغلقه عند الانتهاء.

الآن يمكنك إنشاء ملف main.py لتحديد نقطة الدخول إلى تطبيقك. uWSGI سيقرأ هذا الملف لمعرفة كيفية التفاعل مع التطبيق. قم بتشغيل الأمر التالي لإنشاء ملف main.py  باستخدام nano داخل root directory الخاص بمشروعك:

داخل الملف، أضف السطر التالي الذي سيستورد مثيل Flask الذي تم إنشاؤه في حزمة التطبيق:

الشيء الأخير الذي ستقوم به في هذه الخطوة هو تحديد الاعتماديات اللازمة لتشغيل التطبيق. سنقوم بتحديد هذه الاعتماديات داخل ملف يسمى dependencies.txt. عندما يقوم Docker ببناء صورة تطبيقك، فإنه سيقوم بتنفيذ أمر مدير الحزم pip (package manager) لتثبيت الاعتماديات. افتح الملف في الدليل الجذري باستخدام الأمر التالي:

حتى هذه النقطة في مشروعنا، نريد اعتمادية واحدة فقط: Flask. وبالتالي، يمكننا إضافة السطر التالي للإشارة إلى الإصدار الصحيح من Flask الذي نريده لمشروعنا:

نحن نكتفي بـ Flask version 2.0.1 كاعتمادية. وهو أحدث إصدار في وقت كتابة هذا البرنامج التعليمي. يمكنك معرفة المزيد عن الإصدارات المختلفة من صفحة تغييرات Flask. وبذلك يكتمل إعداد تطبيق Flask. الآن دعنا نجهز تكوينات Docker للنشر.

الخطوة 2: تكوين Docker

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

يحتوي هذا الملف على التكوينات اللازمة لصورة Docker. بعد ذلك، أضف مقتطف الكود التالي لتحديد الاعتماديات وكيفية بناء الصورة:

السطر الأول في Dockerfile يحدد الصورة الأساسية التي نبني صورتنا منها. في هذه الحالة، سنقوم بالبناء بناءً على tiangolo/uwsgi-nginx-flask، المتاحة من DockerHub. لقد اخترنا هذه الصورة بالذات لأنها تدعم العديد من إصدارات Python.

نحدد أيضًا أننا نريد تحديث الصورة. بعد ذلك، نحتاج إلى إضافة bash أمر processo ، ومحرر nano النصوص محرر، وعميل git العميل لسحب ودفع الكود المصدري من مستودعات التحكم في الإصدارات مثل GitHub, Bitbucket, أو Gitlab. السطور التي تحتوي على ENV تحدد متغيرات البيئة التي سيتم استخدامها في الحاوية.

الأمر COPY ينسخ الاعتمادات إلى داخل الحاوية. الأمر RUN يستدعي مدير pip الحزم لتحليل ملف dependencies.txt و تثبيت الاعتمادات. احفظ الملف وأغلقه عند الانتهاء من التعديل.

بعد ذلك، ستقوم بإنشاء برنامج start.sh النصي. سيتضمن هذا البرنامج النصي أوامر Docker لـ بناء و تشغيل الصورة. في حين أنه يمكنك تنفيذ هذه الأوامر تدريجيًا على الطرفية، فقد رأينا أنه من الأفضل إضافتها إلى برنامج شل نصي واستدعائه فقط من الطرفية بأمر واحد.

قبل أن نتمكن من تحديد محتويات هذا الملف، يجب علينا أولاً تحديد منفذ شاغر لا تستخدمه خدمات أخرى. سنستخدم المنفذ 45644. ومع ذلك، يمكنك اختيار منفذ آخر. نفذ السطر التالي للتحقق مما إذا كان المنفذ شاغرًا:

اعتمادًا على المنفذ الذي اخترته، إذا كان مخرج الأمر أعلاه هو 1، فهو شاغر. خلاف ذلك، قد يتعين عليك اختيار منفذ آخر وتجربة الأمر مرة أخرى:

Flask application Port Check

بما أننا قمنا بتحديد منفذ شاغر، يمكننا الآن إنشاء الملف باستخدام nano داخل الدليل الجذري للمشروع عن طريق تشغيل الأمر التالي:

داخل هذا الملف، أضف مقتطف الكود التالي:

السطر الأول، والذي يُشار إليه باسم shebang، يحدد أن هذا ملف bash ويجب تنفيذه كأوامر. يعلن السطر الثاني عن متغير يسمى app_name. نستخدم هذا المتغير لتعيين أسماء الصور والحاويات. يوجه السطر الثالث Docker لـ build الصورة بناءً على تعريف Dockerfile في الدليل الحالي. سيتم تسمية الصورة docker-flask-demo وفقًا للمتغير.

ينشئ السطر الأخير حاوية تسمى docker-flask-demo وفقًا للمتغير الذي حددناه. العلامة -d تبقي الحاوية تعمل في الخلفية في حالة منفصلة بعد انتهاء تنفيذ الأمر. العلامة -p تربط منفذًا على الخادم بمنفذ معين في الحاوية. في هذه الحالة، نقوم بربط المنفذ 45644 على الجهاز المضيف بالمنفذ 80 الذي سيكشفه Docker في الحاوية.

نستخدم العلامة -v لتحديد Docker volume لتركيبه على الحاوية. المتغير $PWD هو متغير Linux افتراضي يحتوي على المسار إلى الدليل الحالي الذي تتواجد فيه في وقت معين:

Flask application pwd

في حالتنا، نقوم بتركيب دليل المشروع بأكمله في الدليل /var/www للحاوية. إعدادات Docker جاهزة الآن. يمكنك بناء الصورة وتشغيل الحاوية بناءً على الصورة المبنية عن طريق تنفيذ الأمر التالي:

انتظر حتى ينتهي البرنامج النصي من التشغيل، ثم نفذ أمر Docker التالي لسرد جميع الحاويات قيد التشغيل:

سيعرض المخرج الحاويات قيد التشغيل:

Demo Docker

يجب أن ترى الحاوية الخاصة بنا بالاسم docker-flask-demo في قائمة الحاويات قيد التشغيل. ابحث عن عنوان العام لخادمكIP وقم بالوصول إليه في متصفحك عبر المنفذ المحدد: http://your-server-public-ip:45644.

يجب أن تشاهد مخرجًا مشابهًا:

Flask App Running

إذا رأيت ما سبق في متصفحك، فهذا يعني أنك قمت بنشر تطبيق Flask بنجاح. بعد ذلك، سنقوم بتعديل الملفات وتقديم المحتوى للمستخدمين عبر القوالب.

الخطوة 3: تقديم المحتوى عبر ملفات القوالب

في Flask، القوالب تُستخدم لعرض المحتوى الثابت والديناميكي لزوار الموقع. سنوضح لك كيفية إنشاء قالب HTML وتقديمه لمستخدميك عندما يزورون مسارًا معينًا. على سبيل المثال، يمكن أن تكون هذه الصفحة الرئيسية أو صفحة "من نحن".

نفذ الأمر التالي في الطرفية لإنشاء ملف index.html في دليل app/templates :

ثم أضف مقتطف الكود التالي إلى الملف:

احفظ الملف وأغلقه عند الانتهاء. أيضًا، قم بإنشاء صفحة أخرى، لنطلق عليها صفحة "من نحن"، بالأمر التالي:

أضف مقتطف الكود التالي إلى الملف:

احفظ الملف وأغلقه عند الانتهاء. بعد ذلك، قم بتعديل ملف app/views.py للإشارة إلى القوالب بالإضافة إلى مسارات الصفحات الفعلية:

قم بتعديل الملف ليصبح على النحو التالي:

احفظ الملف وأغلقه عند الانتهاء. لن تدخل التغييرات التي أجريتها حيز التنفيذ حتى تقوم بإيقاف الحاوية وإعادة تشغيلها. قم بتشغيل أوامر Docker التالية لإيقاف الحاوية وبدئها. انتبه لاسم الحاوية كما حددناه سابقًا:

بمجرد تشغيل الحاوية، قم بزيارة الصفحة الرئيسية وصفحة "حول" لمشاهدة بعض المحتوى الجديد:

Flask application Index

 Flask application 1

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

File Structure

ربما لاحظت أنه كان علينا إعادة تشغيل حاوية Docker لتطبيق التغييرات الجديدة. في الخطوة التالية، سنقوم بأتمتة ذلك لضمان تقليل وقت التوقف.

الخطوة 4: تكوين تحديثات ملفات التطبيق لإعادة التحميل تلقائيًا

بين الحين والآخر نقوم بإجراء تغييرات على التطبيق، لتحسين المنطق، أو واجهات المستخدم، أو إضافة بعض التبعيات. لكي تدخل هذه التغييرات حيز التنفيذ، قد يتطلب الأمر منك إعادة تشغيل حاوية Docker. لحسن الحظ، uWSGI يحتوي على ميزة تسمى touch-reload لإعادة تحميل برنامج Python النصي دون إعادة تشغيل الحاوية.

بشكل افتراضي، يحتوي Python على ميزة auto-reloading التي تراقب نظام الملفات بأكمله بحثًا عن التغييرات وتُحدّث التطبيق عند حدوث أي تغيير. على الرغم من أن إعادة التحميل التلقائي مفيدة لتقليل أوقات التوقف، إلا أنها قد تستهلك الكثير من الموارد. وبالتالي، لا يُنصح بها لبيئات الإنتاج.

دعنا نرى كيف يمكنك استخدام touch-reload لمراقبة التغييرات في ملف معين وإعادة تحميل التطبيق عند حدوث تغييرات. قم بتعديل ملف uwsgi.ini باستخدام محرر nano:

أضف السطر المظلل ليصبح بالشكل التالي:

احفظ الملف وأغلقه عند الانتهاء. يحدد السطر المضاف ملفًا سيتم تعديله لتشغيل إعادة تحميل التطبيق. ومع ذلك، لتنشيط هذا الشرط للتعديلات المستقبلية، يجب عليك أولاً إعادة تشغيل الحاوية:

يمكنك الآن تعديل ملف app/views.py لتوضيح كيفية عمل إعادة التحميل التلقائي:

قم بتغيير السلسلة النصية التي ترجعها دالة home كما هو موضح:

احفظ الملف وأغلقه بمجرد الانتهاء.

افتح الصفحة الرئيسية لتطبيقك في المتصفح: http://your-server-public-ip:45644.

لن ترى أي تغييرات بعد. هذا لأن شرط touch-reload يكتشف التغيير في ملف uwsgi.ini . يمكنك استخدام touch لتنشيط الشرط، وبالتالي إعادة تحميل التطبيق بأكمله باستخدام الأمر التالي:

الآن، إذا قمت بإعادة تحميل الصفحة الرئيسية، ستجد التغييرات الجديدة معروضة:

Touch Reload

في المستقبل، إذا قمت بإجراء أي تغييرات أخرى، فستحتاج فقط إلى تشغيل الأمر sudo touch uwsgi.ini وسيتم إعادة تحميل التطبيق بالكامل مع وقت توقف أقل. هذا ينقلنا إلى نهاية هذا البرنامج التعليمي.

الخاتمة

في هذا البرنامج التعليمي، قمت بتنفيذ ونشر تطبيق Flask باستخدام صور وحاويات Docker. لتقليل وقت التوقف عن العمل عن طريق تجنب الحاجة إلى إعادة تشغيل الحاوية، قمت بتكوين touch-reload للاستماع إلى التغييرات في ملف معين وإعادة تحميل التطبيق بالكامل تلقائيًا. لقد قمت أخيرًا باختبار كل هذا في المتصفح للتأكد من أنه يعمل.

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

لمزيد من الموارد حول Docker على مدونتنا، يمكنك الاطلاع على ما يلي:

حوسبة سعيدة!

author

Pranay Kapgate

المؤلف · CloudSigma

Preslav Dobrev هو مصمم إبداعي في CloudSigma، يركز على هوية أعمال متسقة باستخدام قنوات التسويق التقليدية والمبتكرة. هو بارع في دمج الرؤية الفنية مع التسويق الاستراتيجي لخلق سرد قصصي مؤثر للعلامة التجارية.

التعليقات

لا توجد تعليقات بعد. كن أول من يعلق.