مقدمة
Docker هو منصة حاويات مفتوحة المصدر. وهو بيئة قياسية خفيفة الوزن، وافتراضية، ومحمولة، ومحددة بالبرمجيات تسمح للبرمجيات بالعمل بمعزل عن البرمجيات الأخرى التي تعمل على الجهاز المضيف الفعلي. يوفر Docker بديلاً خفيف الوزن للأجهزة الافتراضية. وفي الوقت نفسه، فإنه يوفر إمكانية النقل والأداء والمرونة وقابلية التوسع للتطبيقات. للحصول على دليل شامل حول نظام Docker البيئي، ألقِ نظرة على نظرتنا العامة المفصلة حول استخدام الحاويات مع Docker.
Flask هو إطار عمل ويب مصغر مفتوح المصدر مبني باستخدام Python. بعض الميزات الرائعة لـ Flask هي أنه خفيف الوزن ومرن ومنظم للغاية. بالإضافة إلى ذلك، لا يتطلب أي أدوات أو إضافات محددة للتشغيل.
يمنحك الجمع بين Flask و Docker تطبيقًا خفيف الوزن ومرنًا وقابلاً للتوسع. يمكنك نشره عبر العديد من الخوادم والبنى التحتية، بفضل الطبيعة المحمولة لحاويات Docker.ينصب تركيز هذا البرنامج التعليمي على توضيح كيفية نشر تطبيق Flask باستخدام Docker. سنوضح أيضًا كيفية التأكد من تفعيل التحديثات المستقبلية لتطبيقك.
المتطلبات الأساسية
سيكون هذا برنامجًا تعليميًا عمليًا، ويجب عليك إنشاء بيئة تمكنك من المتابعة:
- يجب أن يكون لديك تثبيت لنظام Ubuntu 20.04 كبيئة تشغيل أولية لك. تحتاج أيضًا إلى إنشاء مستخدم غير جذري (non-root) يتمتع بصلاحيات sudo.
- بالإضافة إلى ذلك، تحتاج إلى تثبيت Docker. لدينا برنامج تعليمي حول كيفية تثبيت وتشغيل Docker على Ubuntu. اتبع الخطوات 1 و 2 و 3 و 4. يجب أن يعمل هذا مع أي توزيعة Ubuntu.
- أخيرًا، يجب أن يكون لديك Nginx مثبتًا. اتبع برنامجنا التعليمي حول تثبيت Nginx على Ubuntu.
الآن، لنبدأ!
الخطوة 1: تحضير تطبيق Flask
سنبدأ بإنشاء دليل يحتوي على تطبيق Flask الخاص بنا. يمكنك تحديد اسم دليل من اختيارك. ومع ذلك، في هذا البرنامج التعليمي، سنطلق عليه اسم flask_demo. سنقوم بحفظ ملفات المشروع داخل دليل /var/www، وهو عادةً الدليل الذي يسمح Ubuntu بالوصول إليه عبر الإنترنت العام افتراضيًا. أولاً، قم بتنفيذ الأوامر التالية لإنشاء الدليل والانتقال إليه:
|
1 2 3 |
sudo mkdir /var/www/flask_demo cd /var/www/flask_demo |
داخل هذا الدليل الجذري لمشروعنا، سنقوم بإنشاء بنية المجلد الأساسية لتطبيق Flask. بعد ذلك، قم بتنفيذ الأمر التالي لإنشاء البنية الأساسية، مع إضافة العلامة -p لإنشاء جميع المجلدات الأبوية على طول الطريق:
|
1 |
sudo mkdir -p app/static app/templates |
يحتوي مجلد app على جميع الملفات المتعلقة بتطبيق Flask بما في ذلك views و blueprints. تحتوي views على الكود الذي تكتبه للاستجابة للطلبات التي تصل إلى تطبيقك. تساعد blueprints في إنشاء مكونات التطبيق ودعم الأنماط الشائعة في تطبيقات Flask.
مجلد static ذو الاسم المناسب يحتوي على الأصول الثابتة مثل الصور وملفات CSS و JavaScript. بينما يحتوي دليل templates على جميع قوالب HTML الخاصة بالمشروع.
الآن يمكننا البدء في كتابة الملفات اللازمة لتهيئة تطبيق Flask. ابدأ بإنشاء ملف باسم __init__.py داخل دليل app لإخبار Python مفسر بأن دليل app يجب أن يُعامل كحزمة. قم بتنفيذ الأمر التالي على الطرفية لفتح الملف باستخدام محرر nano:
|
1 |
sudo nano app/__init__.py |
نحن نستخدم الحزم في Python لتجميع الوحدات (modules) في مساحات أسماء أو تسلسلات هرمية منطقية. تتيح البرمجة التركيبية (Modularization) تقسيم الكود إلى كتل فردية وسهلة الإدارة تؤدي وظائف محددة.
بعد ذلك، داخل ملف __init__.py المفتوح في المحرر الخاص بك، أضف مقتطف الكود التالي لبدء مثيل Flask، واستيراد المنطق من views.py الذي ستقوم بإنشائه في الخطوات التالية:
|
1 2 3 4 5 |
from flask import Flask app = Flask(__name__) from app import views |
عند الانتهاء، اضغط على Ctrl + O ثم ENTER لحفظ الملف، ثم أغلقه باستخدام Ctrl + X. بعد ذلك، لنقم بإنشاء views.py داخل دليل app . يحتوي ملف views.py على معظم منطق التطبيق:
|
1 |
sudo nano app/views.py |
داخل الملف، أضف مقتطف الكود التالي. سيعرض هذا الكود سلسلة نصية بسيطة لتوضيح أن تطبيقك يعمل عندما يزور المستخدمون موقعك الإلكتروني:
|
1 2 3 4 5 |
from app import app @app.route('/') def home(): return "تطبيق Flask الخاص بنا يعمل!" |
في هذا الملف، نبدأ باستيراد مثيل تطبيق Flask. بعد ذلك، نحتاج إلى إضافة سطر لتحديد المسار: @app.route(/). يُشار إلى سطر @app.route(/) باسم decorator في Flask. يمكنك استخدام الـ decorators لحقن وظائف إضافية في دالة واحدة أو أكثر. في هذه الحالة، نقوم بتمرير استدعاء للمسار / إلى دالة home. عندما يزور المستخدم هذا المسار، سيرى النص: "تطبيق Flask الخاص بنا يعمل!".
بعد ذلك، ستقوم بإنشاء ملف uwsgi.ini للاحتفاظ بتكوينات uWSGI الخاصة بالتطبيق. uWSGI هو خيار نشر لـ Nginx يعمل كبروتوكول وخادم تطبيقات. قم بتشغيل الأمر التالي لإنشاء الملف في الدليل الجذري للمشروع باستخدام محرر nano:
|
1 |
sudo nano uwsgi.ini |
داخل الملف المفتوح، أضف مقتطف الكود التالي:
|
1 2 3 4 |
[uwsgi] module = main callable = app master = true |
يحتوي هذا الملف على بعض التوجيهات. نحدد الغرض منها أدناه:
- module – يحدد الوحدة (module) التي سيتم تقديم تطبيق Flask منها. لقد قمنا بتعيين الوحدة كـ main، مع الإشارة إلى ملف main.py في الدليل الجذري. سنقوم بإنشاء هذا الملف في الخطوة التالية.
- callable – يوجه uWSGI لاستخدام مثيل app المصدر من التطبيق.
- master – يضمن استمرار تشغيل التطبيق لتقليل وقت التوقف أثناء إعادة تحميل التطبيق بالكامل.
احفظ الملف وأغلقه عند الانتهاء.
الآن يمكنك إنشاء ملف main.py لتحديد نقطة الدخول إلى تطبيقك. uWSGI سيقرأ هذا الملف لمعرفة كيفية التفاعل مع التطبيق. قم بتشغيل الأمر التالي لإنشاء ملف main.py باستخدام nano داخل root directory الخاص بمشروعك:
|
1 |
sudo nano main.py |
داخل الملف، أضف السطر التالي الذي سيستورد مثيل Flask الذي تم إنشاؤه في حزمة التطبيق:
|
1 |
from app import app |
الشيء الأخير الذي ستقوم به في هذه الخطوة هو تحديد الاعتماديات اللازمة لتشغيل التطبيق. سنقوم بتحديد هذه الاعتماديات داخل ملف يسمى dependencies.txt. عندما يقوم Docker ببناء صورة تطبيقك، فإنه سيقوم بتنفيذ أمر مدير الحزم pip (package manager) لتثبيت الاعتماديات. افتح الملف في الدليل الجذري باستخدام الأمر التالي:
|
1 |
sudo nano dependencies.txt |
حتى هذه النقطة في مشروعنا، نريد اعتمادية واحدة فقط: Flask. وبالتالي، يمكننا إضافة السطر التالي للإشارة إلى الإصدار الصحيح من Flask الذي نريده لمشروعنا:
|
1 |
Flask==2.0.1 |
نحن نكتفي بـ Flask version 2.0.1 كاعتمادية. وهو أحدث إصدار في وقت كتابة هذا البرنامج التعليمي. يمكنك معرفة المزيد عن الإصدارات المختلفة من صفحة تغييرات Flask. وبذلك يكتمل إعداد تطبيق Flask. الآن دعنا نجهز تكوينات Docker للنشر.
الخطوة 2: تكوين Docker
لإعداد نشر Docker، سنقوم بإنشاء ملفين، Dockerfile و start.sh. يحتوي ملف Dockerfile على سطور تعريفية تشكل صورة Docker. بينما ملف start.sh هو برنامج نصي برمجى أساسي لبناء الصورة وبدء تشغيل الحاوية من Dockerfile. أثناء وجودك داخل الدليل الجذري للمشروع، قم بتنفيذ الأمر التالي لإنشاء Dockerfile:
|
1 |
sudo nano Dockerfile |
يحتوي هذا الملف على التكوينات اللازمة لصورة Docker. بعد ذلك، أضف مقتطف الكود التالي لتحديد الاعتماديات وكيفية بناء الصورة:
|
1 2 3 4 5 6 7 8 9 10 11 |
FROM tiangolo/uwsgi-nginx-flask:python3.6-alpine3.7 RUN apk --update add bash nano git ENV STATIC_URL /static ENV STATIC_PATH /var/www/app/static COPY ./dependencies.txt /var/www/dependencies.txt RUN pip install -r /var/www/dependencies.txt |
السطر الأول في 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 |
sudo nc localhost 45644 < /dev/null; echo $? |
اعتمادًا على المنفذ الذي اخترته، إذا كان مخرج الأمر أعلاه هو 1، فهو شاغر. خلاف ذلك، قد يتعين عليك اختيار منفذ آخر وتجربة الأمر مرة أخرى:

بما أننا قمنا بتحديد منفذ شاغر، يمكننا الآن إنشاء الملف باستخدام nano داخل الدليل الجذري للمشروع عن طريق تشغيل الأمر التالي:
|
1 |
sudo nano start.sh |
داخل هذا الملف، أضف مقتطف الكود التالي:
|
1 2 3 4 5 6 7 |
#!/bin/bash app_name="docker-flask-demo" docker build -t ${app_name} . docker run -d -p 45644:80 --name=${app_name} -v $PWD:/app ${app_name} |
السطر الأول، والذي يُشار إليه باسم shebang، يحدد أن هذا ملف bash ويجب تنفيذه كأوامر. يعلن السطر الثاني عن متغير يسمى app_name. نستخدم هذا المتغير لتعيين أسماء الصور والحاويات. يوجه السطر الثالث Docker لـ build الصورة بناءً على تعريف Dockerfile في الدليل الحالي. سيتم تسمية الصورة docker-flask-demo وفقًا للمتغير.
ينشئ السطر الأخير حاوية تسمى docker-flask-demo وفقًا للمتغير الذي حددناه. العلامة -d تبقي الحاوية تعمل في الخلفية في حالة منفصلة بعد انتهاء تنفيذ الأمر. العلامة -p تربط منفذًا على الخادم بمنفذ معين في الحاوية. في هذه الحالة، نقوم بربط المنفذ 45644 على الجهاز المضيف بالمنفذ 80 الذي سيكشفه Docker في الحاوية.
نستخدم العلامة -v لتحديد Docker volume لتركيبه على الحاوية. المتغير $PWD هو متغير Linux افتراضي يحتوي على المسار إلى الدليل الحالي الذي تتواجد فيه في وقت معين:

في حالتنا، نقوم بتركيب دليل المشروع بأكمله في الدليل /var/www للحاوية. إعدادات Docker جاهزة الآن. يمكنك بناء الصورة وتشغيل الحاوية بناءً على الصورة المبنية عن طريق تنفيذ الأمر التالي:
|
1 |
sudo bash start.sh |
انتظر حتى ينتهي البرنامج النصي من التشغيل، ثم نفذ أمر Docker التالي لسرد جميع الحاويات قيد التشغيل:
|
1 |
sudo docker ps |
سيعرض المخرج الحاويات قيد التشغيل:

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

إذا رأيت ما سبق في متصفحك، فهذا يعني أنك قمت بنشر تطبيق Flask بنجاح. بعد ذلك، سنقوم بتعديل الملفات وتقديم المحتوى للمستخدمين عبر القوالب.
الخطوة 3: تقديم المحتوى عبر ملفات القوالب
في Flask، القوالب تُستخدم لعرض المحتوى الثابت والديناميكي لزوار الموقع. سنوضح لك كيفية إنشاء قالب HTML وتقديمه لمستخدميك عندما يزورون مسارًا معينًا. على سبيل المثال، يمكن أن تكون هذه الصفحة الرئيسية أو صفحة "من نحن".
نفذ الأمر التالي في الطرفية لإنشاء ملف index.html في دليل app/templates :
|
1 |
sudo nano app/templates/index.html |
ثم أضف مقتطف الكود التالي إلى الملف:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Flask Demo</title> </head> <body> <h2>أنت في الرئيسية</h2> <p>مرحبًا بك في صفحة عرض Flask مع Docker</p> </body> </html> |
احفظ الملف وأغلقه عند الانتهاء. أيضًا، قم بإنشاء صفحة أخرى، لنطلق عليها صفحة "من نحن"، بالأمر التالي:
|
1 |
sudo nano app/templates/about.html |
أضف مقتطف الكود التالي إلى الملف:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>حول عرض Flask</title> </head> <body> <h2>صفحة من نحن</h2> <p>هذا كان مشروعًا تجريبيًا. إنه . يوضح كيفية بناء تطبيق build a Flask باستخدام Docker و and Nginx.</p> <p>يمكنك إضافة أي عدد تريده من الصفحات والملفاتas you like</p> </body> </html> |
احفظ الملف وأغلقه عند الانتهاء. بعد ذلك، قم بتعديل ملف app/views.py للإشارة إلى القوالب بالإضافة إلى مسارات الصفحات الفعلية:
|
1 |
sudo nano app/views.py |
قم بتعديل الملف ليصبح على النحو التالي:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
from flask import render_template from app import app @app.route('/') def home(): return "تطبيق Flask الخاص بنا يعمل!" @app.route('/index') def index(): return render_template('index.html') @app.route('/about') def about(): return render_template('about.html') |
احفظ الملف وأغلقه عند الانتهاء. لن تدخل التغييرات التي أجريتها حيز التنفيذ حتى تقوم بإيقاف الحاوية وإعادة تشغيلها. قم بتشغيل أوامر Docker التالية لإيقاف الحاوية وبدئها. انتبه لاسم الحاوية كما حددناه سابقًا:
|
1 |
sudo docker stop docker-flask-demo && sudo docker start docker-flask-demo |
بمجرد تشغيل الحاوية، قم بزيارة الصفحة الرئيسية وصفحة "حول" لمشاهدة بعض المحتوى الجديد:
|
1 |
الرئيسية صفحة: http://your-server-public-ip:45644/index |

|
1 |
حول صفحة: http://your-server-public-ip:45644/about |

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

ربما لاحظت أنه كان علينا إعادة تشغيل حاوية Docker لتطبيق التغييرات الجديدة. في الخطوة التالية، سنقوم بأتمتة ذلك لضمان تقليل وقت التوقف.
الخطوة 4: تكوين تحديثات ملفات التطبيق لإعادة التحميل تلقائيًا
بين الحين والآخر نقوم بإجراء تغييرات على التطبيق، لتحسين المنطق، أو واجهات المستخدم، أو إضافة بعض التبعيات. لكي تدخل هذه التغييرات حيز التنفيذ، قد يتطلب الأمر منك إعادة تشغيل حاوية Docker. لحسن الحظ، uWSGI يحتوي على ميزة تسمى touch-reload لإعادة تحميل برنامج Python النصي دون إعادة تشغيل الحاوية.
بشكل افتراضي، يحتوي Python على ميزة auto-reloading التي تراقب نظام الملفات بأكمله بحثًا عن التغييرات وتُحدّث التطبيق عند حدوث أي تغيير. على الرغم من أن إعادة التحميل التلقائي مفيدة لتقليل أوقات التوقف، إلا أنها قد تستهلك الكثير من الموارد. وبالتالي، لا يُنصح بها لبيئات الإنتاج.
دعنا نرى كيف يمكنك استخدام touch-reload لمراقبة التغييرات في ملف معين وإعادة تحميل التطبيق عند حدوث تغييرات. قم بتعديل ملف uwsgi.ini باستخدام محرر nano:
|
1 |
sudo nano uwsgi.ini |
أضف السطر المظلل ليصبح بالشكل التالي:
|
1 2 3 4 5 |
[uwsgi] module = main callable = app master = true touch-reload = /app/uwsgi.ini |
احفظ الملف وأغلقه عند الانتهاء. يحدد السطر المضاف ملفًا سيتم تعديله لتشغيل إعادة تحميل التطبيق. ومع ذلك، لتنشيط هذا الشرط للتعديلات المستقبلية، يجب عليك أولاً إعادة تشغيل الحاوية:
|
1 |
sudo docker stop docker-flask-demo && sudo docker start docker-flask-demo |
يمكنك الآن تعديل ملف app/views.py لتوضيح كيفية عمل إعادة التحميل التلقائي:
|
1 |
sudo nano app/views.py |
قم بتغيير السلسلة النصية التي ترجعها دالة home كما هو موضح:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
from flask import render_template from app import app @app.route('/') def home(): return "<h3>Some changes to Our Flask application to auto reload!</h3>" @app.route('/index') def index(): return render_template('index.html') @app.route('/about') def about(): return render_template('about.html') |
احفظ الملف وأغلقه بمجرد الانتهاء.
افتح الصفحة الرئيسية لتطبيقك في المتصفح: http://your-server-public-ip:45644.
لن ترى أي تغييرات بعد. هذا لأن شرط touch-reload يكتشف التغيير في ملف uwsgi.ini . يمكنك استخدام touch لتنشيط الشرط، وبالتالي إعادة تحميل التطبيق بأكمله باستخدام الأمر التالي:
|
1 |
sudo touch uwsgi.ini |
الآن، إذا قمت بإعادة تحميل الصفحة الرئيسية، ستجد التغييرات الجديدة معروضة:

في المستقبل، إذا قمت بإجراء أي تغييرات أخرى، فستحتاج فقط إلى تشغيل الأمر sudo touch uwsgi.ini وسيتم إعادة تحميل التطبيق بالكامل مع وقت توقف أقل. هذا ينقلنا إلى نهاية هذا البرنامج التعليمي.
الخاتمة
في هذا البرنامج التعليمي، قمت بتنفيذ ونشر تطبيق Flask باستخدام صور وحاويات Docker. لتقليل وقت التوقف عن العمل عن طريق تجنب الحاجة إلى إعادة تشغيل الحاوية، قمت بتكوين touch-reload للاستماع إلى التغييرات في ملف معين وإعادة تحميل التطبيق بالكامل تلقائيًا. لقد قمت أخيرًا باختبار كل هذا في المتصفح للتأكد من أنه يعمل.
يضمن Docker عمليات نشر أسرع ويسمح بتوسيع نطاق التطبيقات بسهولة. إذا كنت ترغب في معرفة المزيد عن أوامر Docker المختلفة، يرجى إلقاء نظرة على هذا البرنامج التعليمي حول كيفية تثبيت واستخدام Docker على Ubuntu.
لمزيد من الموارد حول Docker على مدونتنا، يمكنك الاطلاع على ما يلي:
- تقنية الحاويات: أنواع واستخدامات الحاويات المختلفة على منصة PaaS الخاصة بـ CloudSigma
- كيفية مشاركة البيانات بين حاوية Docker والمضيف
- تثبيت وإعداد Docker على CentOS 7
- نشر Laravel و Nginx و MySQL باستخدام Docker Compose
- تنظيف موارد Docker - الصور والحاويات ووحدات التخزين
حوسبة سعيدة!
التعليقات
لا توجد تعليقات بعد. كن أول من يعلق.