اذهب إلى المحتوى

تخديم تطبيقات فلاسك باستخدام خادمي الويب uWSGI و Nginx


محمد الخضور

سننشئ في هذا المقال تطبيق بايثون باستخدام إطار العمل المُصغّر فلاسك Flask في الإصدار 20.04 من توزيعة أبونتو، سيتضمّن القسم الأكبر من هذا المقال معلومات حول كيفية إعداد خادم تطبيق uWSGI وكيفية الوصول إلى هذا التطبيق وآلية إعداد خادم Nginx ليعمل مثل خادم وكيل معكوس reverse proxy لدى طرف المستخدم.

مستلزمات العمل

قبل المتابعة في هذا المقال لا بدّ من:

  • توفّر خادم مثبّت عليه نظام تشغيل أبونتو 20.04 ذو مستخدم عادي ليس مستخدم جذر root وبصلاحيات sudo، مع تفعيل جدار الحماية.
  • تثبيت خادم Nginx.
  • خادم نطاق أسماء للإشارة إلى خادم التطبيق، إذ من الممكن شراء نطاق من Namecheap أو الحصول على نطاق مجاني من Freenom، وفي مقالنا سنفترض أنّ خادم نطاق الأسماء DNS يحوي السجلات التالية:
  • سجل من النوع A يحمل القيمة "your_domain" ويشير إلى عنوان IP العام المُخصّص لخادم التطبيق.
  • سجل من النوع A يحمل القيمة "www.your_domain" يشير إلى عنوان IP العام المُخصّص لخادم التطبيق.

إضافةً لما سبق يُفضّل وجود معرفة جيدة بالتعامل مع خادم uWSGI، ومع الخادم الذي سننشئ عليه التطبيق، والفهم الجيد لمواصفات وخصائص بروتوكول WSGI.

الخطوة الأولى - تثبيت المكونات اللازمة من مستودعات أبونتو

سنثبّت في هذه الخطوة كافّة المكونات التي سنحتاجها من مستودع أبونتو، إضافةً إلى مدير تثبيت حزمة بايثون "pip" لإدارة مكونات بايثون، كما سننزّل ملفات تطوير بايثون الضرورية لبناء خادم "uWSGI".

بدايةً سنحدّث موقع دليل الحزمة المحلي:

$ sudo apt update

ثمّ سنثبّت الحزم اللازمة لبناء بيئة بايثون والتي تشمل الحزمة "python3-pip" وغيرها من الحزم وأدوات التطوير الضرورية للحصول على بيئة برمجية مستقرّة ومتينة:

$ sudo apt install python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools

الآن وبعد الانتهاء من تثبيت الحزم ننتقل إلى إنشاء البيئة الافتراضية اللازمة لمشروعنا.

الخطوة الثانية – إنشاء بيئة بايثون افتراضية

سنُعِد في هذه الخطوة البيئة الافتراضية اللازمة لفصل تطبيق فلاسك عن ملفات بايثون الأُخرى في النظام.

سنبدأ بتثبيت الحزمة "python-venv" المسؤولة عن تحميل حزم بايثون ضمن بيئة معزولة خاصّة بكل مشروع، والتي ستتثبّت بدورها الوحدة "venv":

$ sudo apt install python3-venv

الآن سننشئ المجلد الرئيسي لمشروع فلاسك:

$ mkdir ~/myproject

ثمّ سننتقل إلى هذا المجلد كما يلي:

$ cd ~/myproject

وفيه سننشئ البيئة الافتراضية اللازمة لتخزين متطلبات بايثون التي سيحتاجها مشروع فلاسك، وذلك بتنفيذ الأمر التالي:

$ python3.6 -m venv myprojectenv

سيثبّت الأمر السابق نسخةً محليةً من بيئة بايثون ومن الحزمة "pip" في مجلد باسم "myprojectenv" ضمن المجلد الرئيسي للتطبيق.

والآن، لا بدّ من تفعيل هذه البيئة الافتراضية قبل تثبيت أي تطبيقات ضمنها على النحو التالي:

$ source myprojectenv/bin/activate

وهنا نلاحظ تغيّر مؤشّر واجهة أسطر الأوامر ليشير إلى عملنا ضمن البيئة الافتراضية ليصبح على الشّكل:

(myprojectenv)user@host:~/myproject$

الخطوة الثالثة - إعداد تطبيق فلاسك

الآن، وبعد تفعيل البيئة الافتراضية والعمل ضمنها، أصبح بالإمكان تثبيت فلاسك وخادم "uWSGI" لنباشر بتصميم التطبيق.

سنثبّت بدايةً المكوّن "wheel" مع استخدام مُثبّت الحزم "pip"، وبذلك نتأكّد من تثبيت وعمل الحزم بصورةٍ سليمة حتّى في حال عدم وجود "wheel".

$ pip install wheel

ملاحظة: بغض النظر عن إصدار بايثون المُستخدم، يجب استخدام الأمر pip وليس pip3 عندما تكون البيئة الافتراضية قيد التشغيل.

سنثبّت الآن فلاسك وخادم uWSGI:

(muprojectenv) $ pip install uwsgi flask

وبعد انتهاء التثبيت، يمكننا البدء باستخدام فلاسك.

إنشاء تطبيق بمثابة عينة للاختبار

الآن، وبعدما أصبح فلاسك جاهزًا، يمكننا الشروع بإنشاء تطبيق بسيط، فكما نعلم فإن فلاسك إطار عمل مًصغّر، لا يحتوي على كثيرٍ من الأدوات مثل تلك التي يمتلكها إطار العمل كامل الميزات، إذ أن فلاسك بالأصل هو مُجرّد وحدة نستوردها إلى مشاريعنا للمساعدة في تهيئة تطبيق الويب.

وطالما أنّ التطبيق ككل قد يصبح أكثر تعقيدًا لاحقًا بإضافة مكونات أُخرى عليه، سننشئ تطبيق فلاسك ضمن ملف واحد باستخدام أي محرّر نصوص تفضّله، وفي مقالنا سنستخدم محرّر نانو nano وسنسمّي الملف "myproject.py":

(muprojectenv) $ nano ~/myproject/myproject.py

أي ستُخزّن الشيفرة الخاصّة بالتطبيق في هذا الملف، وفيها سنستورد فلاسك وننشئ كائن فلاسك الذي سنستخدمه لتعريف الدوال التي ستعمل لدى طلب اتجاهٍ معينة من قبل المُستخدم:

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "<h1 style='color:blue'>Hello There!</h1>"

if __name__ == "__main__":
    app.run(host='0.0.0.0')

حدّدنا في الشيفرة السابقة المحتوى الذي سيُعرض عند الدخول إلى النطاق الأساسي للتطبيق.

نحفظ الملف ونغلقه بالضغط على مفتاحي "CTRL+X"، ثمّ "Y"، ثمّ "ENTER" في حال كنت تستخدم محرّر النصوص نانو.

وباتباع خطوات إعداد الخادم الابتدائي سيكون جدار حماية UFW قيد التشغيل، وبالتالي لن نتمكّن من الوصول إلى لتطبيق لاختباره ما لم نسمح بالوصول إلى المنفذ 5000 كما يلي:

(muprojectenv) $ sudo ufw allow 5000

سنختبر الآن تطبيق فلاسك:

(muprojectenv) $ python myproject.py

فيكون الخرج مُشابهًا لما يلي، والذي يتضمّن تحذيرات مهمّة ومفيدة تشير لعدم استخدام إعداد الخادم هذا (خادم التطوير) في مرحلة الاستخدام الفعلي للتطبيق (نشر المُنتج).

* Serving Flask app "myproject" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

الآن وباستخدام المتصفح ننتقل إلى عنوان IP الخاص بالخادم متبوعًا برقم المنفذ الخاص بالتطبيق "5000:" على النحو التالي:

http://your_server_ip:5000

فتكون النتيجة مُشابهةً لما يلي:

1st_test_app.png

وعند الانتهاء نضغط على "CTRL + C" في نافذة مشغّل الأوامر لإيقاف خادم تطوير فلاسك.

إنشاء نقطة دخول لتطبيق WSGI

في هذه الخطوة سننشئ ملفًا ليعمل مثل نقطة دخول إلى التطبيق، والتي سترشد خادم uWSGI لآلية التفاعل مع التطبيق، لذا سننشئ ملفاً باسم "wsgi.py":

(muprojectenv) $ nano ~/myproject/wsgi.py

سنستورد في هذا الملف نسخة فلاسك من التطبيق ونشغلها:

from myproject import app

if __name__ == "__main__":
    app.run()

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

الخطوة 4 – إعداد خادم uWSGI

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

اختبار خادم uWSGI

بدايةً وقبل إجراء مزيدٍ من التغييرات، من المفيد اختبار ما إذا كان uWSGI قادرًا على تخديم تطبيقنا هذا، وذلك بتمرير اسم نقطة الدخول المكوّن من اسم الوحدة المُستخدمة بدون اللاحقة "py." مع اسم الاستدعاء داخل التطبيق، وبالتالي في حالتنا سيكون اسم نقطة الدخول هو "wsgi:app".

كما أنّنا سنحدّد مقبس ويب للخادم ليعمل على واجهة عامّة، مُستخدمًا بروتوكول HTTP عوضًا عن بروتوكول uwsgi الثنائي، باستخدام نفس رقم المنفذ "5000" المفتوح أصلًا:

(muprojectenv) $ uwsgi --socket 0.0.0.0:5000 --protocol=http -w wsgi:app

وبالانتقال إلى رابط الخادم (عنوان IP الخاص به) متبوعًا برقم المنفذ "5000:" باستخدام المتصفح:

http://your_server_ip:5000

يجب أن نحصل على نفس خرج التطبيق، أي:

1st_test_app.png

وبعد التأكد من كون الخادم يعمل كما يجب، نضغط "CTRL +C" في نافذة الطرفية لإيقاف تشغيله.

وفي هذه المرحلة ومع الانتهاء من إعداد البيئة الافتراضية، أصبح من الممكن إلغاء تفعيلها:

(muprojectenv) $ deactivate

وبذلك فإنّ أي أوامر بلغة بايثون ستستخدم بيئة بايثون الموجودة فعليًا على النظام.

إنشاء ملف ضبط uWSGI

الآن وبعد ما اختبرنا وتأكدنا من قدرة uWSGI على تخديم تطبيقنا (تمكنّا من الوصول إلى خرج التطبيق من خلاله)، ولضمان عمل فعّال وموثوق للتطبيق على المدى الطويل سننشئ ملفًا ضبط uWSGI مُتضمّنًا كافّة الخيارات اللازمة لذلك.

سننشئ هذا الملف ضمن مجلد التطبيق الرئيسي باسم "myproject.ini":

$ nano ~/myproject/myproject.ini

سنبدأ بداخله بالترويسة [uwsgi]، التي تتضمّن الإعدادات الواجب على خادم uWSGI تطبيقها، وفيها سنحدّد الوحدة المُستخدمة وهي في حالتنا "wsgi.py"، إذ نكتب اسمها دون اللاحقة، مع اسم الاستدعاء إلى uWSGI داخل التطبيق وهو "app" على النحو التالي:

[uwsgi]
module = wsgi:app

ومن ثمّ كتبنا الأمر اللازم لتشغيل خادم uWSGI في الوضع الرئيسي Master mode مولدًّا خمس عمليات تابعة لتلك الرئيسية لتخديم الطلبات الفعليّة:

[uwsgi]
module = wsgi:app

master = true
processes = 5

ومن الجدير بالملاحظة أنّنا وفي مرحلة الاختبار فتحنا منفذًا مُباشرًا لخادم uWSGI، ولكن بما أنّنا سنستخدم خادم Nginx تاليًا للتعامل مع اتصالات العملاء (زوّار التطبيق) ليمرّر بدوره الطلبات إلى خادم uWSGI، وبما أن هذين المكونين يعملان على حاسوبٍ واحد، فمن المفضّل استخدام مقبس ويب يونكس Unix كونه أسرع وأكثر أمنًا، لذا سنستدعي المقبس "myproject.sock" لنضمّنه في مجلدنا هذا.

كما سنغيّر أذونات مقبس الويب هذا بما يمنح خادم Ngnix ملكية عمليات خادم uWSGI، لذا يجب التأكّد من كون مالك المقبس لديه أذونات القراءة منه والكتابة عليه، كما سنفعّل خيار تنظيف المقبس لدى توقّف العمليات بإضافة الخيار vacuum:

[uwsgi]
module = wsgi:app

master = true
processes = 5

socket = myproject.sock
chmod-socket = 660
vacuum = true

ونهايةً سنضيف خيار die-on-term، وبذلك نضمن أنّه لدى كل من النظام المُهيئ وخادم uWSGI نفس الافتراضات حول معنى كل عملية، وبذلك تعمل مكونات النظامين على التوازي وصولًا إلى النتيجة المطلوب تنفيذها.

[uwsgi]
module = wsgi:app

master = true
processes = 5

socket = myproject.sock
chmod-socket = 660
vacuum = true

die-on-term = true

نلاحظ أنّنا في هذه الخطوة لم نُحدّد بروتوكولًا كما فعلنا في نافذة أسطر الأوامر سابقًا، ذلك لأنّ خادم uWSGI يستخدم بروتوكول uwsgi افتراضيًا، وهو بروتوكول سريع يتعامل مع النظام الثنائي للعد (يستخدم كامل قيم البايت الواحد)، مُصمّم للتواصل مع الخوادم الأخرى، وخادم Nginx قادرٌ أصلًا على التخاطب معه، وبالتالي يُعد استخدام هذا البروتوكول أفضل من فرض الاتصال باستخدام بروتوكول HTTP.

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

الخطوة الخامسة - إنشاء ملف وحدة الاتصال مع النظام

سننشئ في هذه الخطوة ملف وحدة الاتصال التي ستسمح لنظام أوبنتو المُهيّأ أصلًا بتشغيل خادم uWSGI تلقائيًا ليخدّم التطبيق في كل مرة يُشغّل فيها الخادم الفعلي.

سننشئ هذا الملف ضمن المسار "etc/system/system/" مع ملاحظة أنّ لاحقته هي "service." كما يلي:

$ sudo nano /etc/systemd/system/myproject.service

وضمن الملف نكتب الشيفرة بدءًا من القسم [Unit] الذي نحدّد من خلاله البيانات الوصفية metadata ومتطلبات العمل، وفيه نصف طبيعة الخدمة ونجعل النظام الفعلي المُهيّأ يبدأ بالعمل فقط بعد إنتهاء عمليات الربط الشبكي المطلوبة:

[Unit]
Description=uWSGI instance to serve myproject
After=network.target

بعدها نكتب القسم [Service]، وفيه نحدّد مكان تنفيذ العمليات، أي المُستخدم والمجموعة الهدف، إذ سنعطي حساب المُستخدم العادي صلاحيات المالك كونه يملك بالفعل كافّة الملفات ذات الصلة بالعمليات الجارية، كما سنعطي المجموعة www-data صلاحيات مالك المجموعة بما يضمن تخاطب سهل ما بين خادم Nginx وعمليات uWSGI الجارية، ومن الضروري في هذا المقطع استبدال اسم المُستخدم بالاسم الخاص بك، كما يلي:

[Unit]
Description=uWSGI instance to serve myproject
After=network.target

[Service]
User=username
Group=www-data

سنحدّد الآن مجلد العمل، كما سنضبط قيمة متغير البيئة PATH بما يُعلِم النظام الفعلي المُهيّأ بأنّ ملفات تشغيل العمليات موجودةٌ ضمن البيئة الافتراضية، كما سنحدّد الأمر البرمجي المسؤول عن بدء تشغيل الخدمة، والذي يتطلّب تمرير المسار الكامل إلى ملف تشغيل uWSGI المُثبّت في البيئة الافتراضية، كما سنمرر اسم ملف الضبط ذو اللاحقة "ini." الذي أنشأناه أصلًا في مجلد المشروع.

ومن المهم استبدال اسم المستخدم username ومسار المشروع بما يتوافق مع معلوماتها لديك.

[Unit]
Description=uWSGI instance to serve myproject
After=network.target

[Service]
User=username
Group=www-data
WorkingDirectory=/home/username/myproject
Environment="PATH=/home/username/myproject/myprojectenv/bin"
ExecStart=/home/username/myproject/myprojectenv/bin/uwsgi --ini myproject.ini

أمّا الآن فسنضيف القسم [Install]، الذي يُعلم النظام المُهيّأ بمكان ربط الخدمة التي ستبدأ فور إقلاع النظام، إذ أنّ المطلوب في حالتنا جعل الخدمة تبدأ فور إعداد وتشغيل نظام مُستخدمي التطبيق العاديين:

[Unit]
Description=uWSGI instance to serve myproject
After=network.target

[Service]
User=username
Group=www-data
WorkingDirectory=/home/username/myproject
Environment="PATH=/home/username/myproject/myprojectenv/bin"
ExecStart=/home/username/myproject/myprojectenv/bin/uwsgi --ini myproject.ini

[Install]
WantedBy=multi-user.target

وبذلك يكون ملف الخدمة الخاصّ بالنظام الفعلي المُهيّأ جاهزًا. احفظ هذا الملف واغلقه.

الآن، سنشغّل خدمة uWSGI التي أنشأناها وجعلناها تبدأ فور الإقلاع:

$ sudo systemctl start myproject
$ sudo systemctl enable myproject

ونتحقّق من حالة عملها كما يلي:

$ sudo systemctl status myproject

إذا كانت تعمل بصورةٍ صحيحة، فيجب أن نحصل على خرج شبيه بما يلي:

 myproject.service - uWSGI instance to serve myproject
     Loaded: loaded (/etc/systemd/system/myproject.service; enabled; vendor preset: enabled)
     Active: active (running) since Wed 2020-05-20 13:21:39 UTC; 8h ago
   Main PID: 22146 (uwsgi)
      Tasks: 6 (limit: 2345)
     Memory: 25.5M
     CGroup: /system.slice/myproject.service
             ├─22146 /home/sammy/myproject/myprojectenv/bin/uwsgi --ini myproject.ini
             ├─22161 /home/sammy/myproject/myprojectenv/bin/uwsgi --ini myproject.ini
             ├─22162 /home/sammy/myproject/myprojectenv/bin/uwsgi --ini myproject.ini
             ├─22163 /home/sammy/myproject/myprojectenv/bin/uwsgi --ini myproject.ini
             ├─22164 /home/sammy/myproject/myprojectenv/bin/uwsgi --ini myproject.ini
             └─22165 /home/sammy/myproject/myprojectenv/bin/uwsgi --ini myproject.ini

وفي حال وجود أي رسائل أخطاء، يجب إيجاد حلول لها قبل المتابعة في الخطوات التالية، أو يمكنك الانتقال لضبط تثبيت Nginx لتمرير الطلبات إلى مقبس "myproject.sock".

الخطوة السادسة - ضبط Nginx ليعمل مثل خادم وكيل

مع بداية هذه الخطوة يجب أن يكون خادم uWSGI الخاص بالتطبيق جاهزًا وقيد التشغيل، بانتظار الطلبات الواردة إلى ملف مقبس الويب المُنشأ في مجلد المشروع، وفي هذه الخطوة سنضبط خادم Nginx ليمرر طلبات الويب إلى المقبس آنف الذكر باستخدام بروتوكول "uwsgi".

لذا، سننشئ ملف ضبط جديد للخادم باسم "myproject" ضمن المجلد "sites-available" الخاص بخادم Nginx:

$ sudo nano /etc/nginx/sites-available/myproject

وسنكتب ضمن هذا الملف الشيفرة اللازمة لجعل خادم Nginx يصغي للمنفذ الافتراضي ذو الرقم "80" بانتظار أي طلبات واردة، كما سيستخدم هذه الشيفرة أيضًا للتعامل مع طلبات الوصول عن طريق اسم مجال خادم التطبيق.

server {
    listen 80;
    server_name your_domain www.your_domain;
}

إذ سنضيف مجموعة شيفرات متوافقة مع كل موقع مطلوب، وفيها سنضمّن الملف "uwsgi_params" المسؤول عن تحديد معاملات uWSGI الواجب ضبطها، ثمّ سنمرر الطلبات إلى ملف مقبس الويب المُعرّف أصلًا باستخدام الموجّه uwsgi_pass:

server {
    listen 80;
    server_name your_domain www.your_domain;

    location / {
        include uwsgi_params;
        uwsgi_pass unix:/home/sammy/myproject/myproject.sock;
    }
}

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

ولتمكين ملف كتلة إعدادات خادم Nginx هذا، سنربطه مع المجلد "sites-enabled" كما يلي:

$ sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled

عند تثبيت مخدم Nginx، يجري إعداد ملف ضبط للمخدم اسمه "default" ضمن المجلد "sites-available"، ثم يُنشأ ارتباط رمزي بين هذا الملف والمجلد "sites-available"؛ فإذا تركت هذا الارتباط الرمزي مكانه، فسيمنع الضبط الافتراضي "default" موقعك من التحميل.

يمكنك إزالة هذا الرابط باستخدام الأمر التالي:

$ sudo unlink /etc/nginx/sites-enabled/default

وسنتمكّن مع وجود الملف ضمن المجلد من فحص أي أخطاء في الصياغة البرمجية باستخدام الشيفرة التالية:

$ sudo nginx -t

وفي حال عدم ظهور أي أخطاء (أي قيمة معادة لدى تنفيذ الشيفرة السابقة)، نعيد تشغيل عملية Nginx لتتعرّف على الضبط الجديد:

$ sudo systemctl restart nginx

والآن أصبح من الممكن تعديل جدار الحماية مُجدّدًا، إذ أنّنا لم نعد بحاجة إلى الوصول عبر المنفذ "5000"، لذا سنحذف هذا الاستثناء:

$ sudo ufw delete allow 5000

ثمّ سنسمح بالوصول إلى خادم Nginx على النحو التالي:

$ sudo ufw allow 'Nginx Full'

وبذلك يصبح من الممكن الوصول إلى التطبيق باستخدام اسم المجال الخاص بالخادم عبر المتصفح:

http://your_domain

فيظهر لنا خرج التطبيق بالشّكل التالي:

1st_test_app.png

أمّا إذا واجهت أي أخطاء، فعليك التحقّق منها مُستخدمًا الأوامر التالية:

  • sudo less /var/log/nginx/error.log: للتحقّق من سجل أخطاء خادم Nginx.
  • sudo less /var/log/nginx/access.log: للتحقّق من سجل الوصول إلى خادم Nginx.
  • sudo journalctl -u nginx: للتحقّق من سجل عمليات خادم Nginx.
  • sudo journalctl -u myproject: للتحقّق من سجل خادم uWSGI الخاص بتطبيق فلاسك.

الخطوة السابعة - تأمين التطبيق

لضمان اتصال ونقل بيانات آمن ومُشفّر من وإلى خادم التطبيق، لا بُدّ من الحصول على شهادة طبقة مقابس الويب الآمنة Secure Socket Layer -أو اختصارًا SSL-؛ وهي شهادةٌ رقميةٌ تصادق على هوية موقع الويب وتتيح اتصالاً مشفرًا، ومن الممكن الحصول على هذه الشهادة مجانًا من Let's Encypt (وهي هيئة شهادات مجانية تابعة لمجموعة أبحاث أمن الإنترنت)، أو إنشاء شهادة خاصّة بك، ناهيك عن وجود طرق عديدة للحصول على الشهادة.

لذا بدايةً سنثبّت حزمة Certbot وإضافات Nginx الخاصة به باستخدام apt:

$ sudo apt install certbot python3-certbot-nginx

يؤمن Certbot عدة طرق مختلفة للحصول على شهادة SSL من خلال هذه الإضافات plugins، وبعد تثبيت إحداها ستعمل إضافة Nginx من تلقاء نفسها على إعادة ضبط إعدادات الخادم وإعادة تحميلها كلما دعت الحاجة لذلك، ولاستخدام هذه الإضافة سنشغّل الأمر:

$ sudo certbot --nginx -d your_domain -d www.your_domain

تشغّل الشيفرة السابقة certbot مع إضافة nginx–، وقد استخدمنا d- لتحديد الأسماء المتوافقة مع الشهادة.

إذا كانت هذه المرة الأولى التي تشغّل فيها certbot على الخادم، سيتطلّب الأمر إدخال بريد إلكتروني والموافقة على شروط الخدمة، بعدها ستتواصل certbot مع خادم Let’s Encrypt، ثم تشغّل نظام تحقّق للتأكد من أنّك تتحكم فعلًا بالنطاق الذي تطلب الشهادة من أجله.

فإذا انتهت العملية السابقة بنجاح، سيطلب منا certbot ضبط الإعدادات التي نريد لبروتوكول HTTPS:

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
-------------------------------------------------------------------------------
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
-------------------------------------------------------------------------------
Select the appropriate number [1-2] then [enter] (press 'c' to cancel):

في هذه الخطوة نختار ما نريده من إعدادات ثمّ نضغط على مفتاح "ENTER" لتحديث الضبط، كما يُعاد تحميل Nginx لتطبيق الإعدادات الجديدة هذه، ونهايةً يعرض certbot رسالةً مفادها نجاح العملية وموقع تخزين الشهادة:

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/your_domain/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/your_domain/privkey.pem
   Your cert will expire on 2020-08-18. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot again
   with the "certonly" option. To non-interactively renew *all* of
   your certificates, run "certbot renew"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

وإذا اتبعنا تعليمات تثبيت Nginx كما هو موضّح في فقرة مستلزمات العمل من هذا المقال، فلن نعود بحاجة لسماحية ملف تعريف HTTP:

$ sudo ufw delete allow 'Nginx HTTP'

الآن وللتحقّق من الإعدادات سننتقل مجدّدًا إلى النطاق الخاص بالتطبيق باستخدام "//:https":

https://your_domain

وهنا يجب أن يظهر خرج التطبيق مجدّدًا ولكن مع مؤشر الأمان الخاص بالمتصفح والذي يشير إلى أنّ الموقع آمن.

الخاتمة

في هذا المقال أنشأنا تطبيق فلاسك صغير آمن باستخدام بيئة بايثون افتراضية، وأنشأنا نقطة دخول إلى بروتوكول WSGI بحيث يتمكّن أي خادم تطبيق متوافق مع WSGI من التعامل معه، إذ أعددنا خادم uWSGI ليؤدي هذه المهمة، بعدها أنشأنا ملف تخديم مسؤول عن الوصول آليًا خادم التطبيق لدى إقلاع الخادم الفعلي، كما أنشأنا كتلة خادم Nginx التي تمرّر حركة مرور مستخدم الويب إلى خادم التطبيق، وبالتالي تُرحل طلبات مستخدمي التطبيق الخارجية وحركة المرور الآمنة إلى الخادم مع خادم Let's Encrypt.

وبذلك نجد أنّ فلاسك إطار عمل مرن جدًا، إذ يمنح التطبيقات القدرة على العمل الفعلي دون التقيد بالهيكل والتصميم، ويمكنك استخدام ما ذُكر في هذا المقال لتخديم أي تطبيق فلاسك ترغب بتصميمه.

ترجمة -وبتصرف- للمقال How To Serve Flask Applications with uWSGI and Nginx on Ubuntu 20.04 لصاحبه Mark Drake و Kathleen Juell.

اقرأ أيضًا


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...