سننشئ في هذا المقال تطبيق بايثون باستخدام إطار العمل المُصغّر فلاسك 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
فتكون النتيجة مُشابهةً لما يلي:
وعند الانتهاء نضغط على "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
يجب أن نحصل على نفس خرج التطبيق، أي:
وبعد التأكد من كون الخادم يعمل كما يجب، نضغط "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
فيظهر لنا خرج التطبيق بالشّكل التالي:
أمّا إذا واجهت أي أخطاء، فعليك التحقّق منها مُستخدمًا الأوامر التالية:
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.
تعليقات
إرسال تعليق