كيف تستضيف تطبيقك محلياً Self-hosting

تستخدم خدمات اونلاين كثير؟ تدوين, بريد الكتروني او حتى تخزين ملفات على السحابة. أكيد كلنا نستخدم بعض الخدمات وبشكل يومي وتقريباً كلها خدمات جاهزة للاستخدام مباشرة و نقدر نبدأ في ارسال الايملات على Gmail او نكتب تدوينة على wordpress او نرفع ملفات على dropBox او حتى نغرد على تويتر, كل هذا نسويه بسهولة بمجرد التسجيل في الخدمة المرغوبة.

طيب.. تبي تبني احد الخدمات السابقة بنفسك من الصفر؟ تبي تسخدم سطر الاوامر وتعدل ملفات اعدادت؟ تبي كل فترة تسوي تحديثات يدوية وممكن تخبص عليك و تضطر تعيد كل شي من جديد؟ تبي وجع راس؟! 😬 لالا معليش مش وجع راس.. تبي تتعلم احدى طرق استضافة التطبيقات في الشركات؟ تبي تشغل تطبيق خاص فيك اونلاين؟ تبي تسوي لك مدونة زي هذي اونلاين بدون سيرفر خاص او بدون خدمة مدفوعة وتتحكم في كامل بياناتك؟

واحد من المصطلحات الشائعة في الوسط التقني وبين المطورين او اصحاب السيرفرات المنزلية هو Self-hosting وهذا هو موضوعي اليوم وبوضح ايش هو و الهدف منه وكيف تقدر تستفيد منه.

ما هو الـ Self-hosting

هو تثبيت وتشغيل وصيانة واعداد ومتابعة التطبيق (او الموقع) بنفسك 😱 سواء على جهازك في البيت او من خلال سيرفرك الخاص وبدون استئجار موارد التطبيق من مقدمي الخدمات SaaS. مافي ترجمة مناسبة للمصطلح بس خلونا نكمل باقي التدوينة بهذي الترجمة الاستضافة الذاتية

كثير يسألني كيف يكون عندك سيرفر او يعتقد ان السيرفر لازم يكون جهاز ضخم و بمعالج قوي وذاكرة كبيرة. لازم تعرف ان اي جهاز ممكن يكون سيرفر حتى جهازك العادي في البيت او لابتوبك او حتى كمبيوتر صغير مثل الرازبيري بسعر 100 ريال او حتى جوالك! و الفكرة الرئيسية في السيرفرات انه يكون شغال على طول!

ما الهدف من الـ Self-hosting

بعيد عن بقية مقالات الانترنت وبشكل بسيط, في رأيي اهم هدف و ميزة في الاستضافة الذاتية هو التعلم والاطلاع خصوصاً لمن يعمل في او يحب مجال تقنية المعلومات, والتعلم في هذا الموضوع مو بس في التطبيق او الموقع وطريقة تشغيله فقط بل ممكن تتعلم و تستخدم سطر الاوامر وتعدل على الملفات من خلاله, بتقدر تتعرف على أدوات كثير ممكن تسهل عليك شغلك مستقبلا, او تجرب تشغيل تطبيقات مفتوحة المصدر وتعدل عليها لو تحب وتشوف نتجية تعديلك مباشرة .. وممكن هذا كله يكون متعة لك في الاخير ويكون هدفك الرئيسي. 👌🏻

في اسباب ثانية تقدر تحطها في بالك لو تحب تعمل استضافة ذاتية وهي:

  1. متابعة اخر مستجدات التطبيقات او تجربة نسخة جديدة قبل الانتقال لها. Testing
  2. الحماية والخصوصية, بيكون التطبيق تحت تحكمك بالكامل ومحد يقدر يطلع على البيانات الخاصة (بالمناسبة كل الشركات تمتلك و تتطلع على بياناتنا ومعلوماتنا مثل قوقل ومايكروسوفت وامازون وفيسبوك وكلنا مانهتم 💩).
  3. الاستضافة الذاتية ماتكلف شي لو سويتها من جهاز في بيتك, او ممكن تكلف شي بسيط على السحابه مع اماكنية تشغيل تطبيقات كثيرة.

بدايتي مع الاستضافة الذاتية كانت مع اول سيرفر Synology وقتها كان عندي قائمة كبيره لملفات تورنت لمواقع خاصه واحتاج اخليها شغاله على طول, عملت selfhost للتطبيق الشهير rtorrent وسويت seedbox خاص بكامل إضافاته كتبت عنه هنا, و وقت ماتنزل حلقه او فلم ابي اشوفه الاقيه جاهز او ادخل من خارج الشبكة وأبدأ تنزيله.

امثلة لتطبيقات تقدر تستضيفها محليا self-hosted apps

اول شي هنا قائمة كبيرة لتطبيقات مفتوحة المصدر تقدر تتطلع عليها وتاخذ فكرة عن التطبيقات الرائعة الي تقدر تسويها.

  • اذا عندك تطبيق خاص برمجتة وتبي تشغلة اون لاين تقدر تشغلة بهذي الطريقة.
  • تقدر تعمل الدروب بوكس او الدرايف الخاص فيك باستخدام Nextcloud.
  • تقدر تشغل مكتبة افلامك ومسلسلاتك باستخدام plex او jellyfin وتشوفها من اي مكان لو اتصالك سريع.
  • تقدر تشغل سيرفر قواعد بيانات خاص فيك.
  • تقدر تسوي الشات الخاص فيك باستخدام Rocket chat.

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


كيف تبدأ مع الـ Self-hosting

طرق الاستضافة كثيرة ومنوعة و في هذي التدوينة بركز على طريقة بسيطة باستخدام دوكر (docker) لتشغيل التطبيق (سوا برمجة خاصة او تطبيق وبرنامج منشور), واستخدام nginx reverse proxy لتحويل وتوجيه الطلبات للتطبيق المرغوب.

  • ولذلك هذه التدوينة تفترض ان يكون لديك اساسيات دوكر docker (تقدر تشوف شرح بسيط هنا)
  • وتفترض ان يكون docker مثبت عندك.

تقدر تسوي الشغل على دوكر في الويندوز لكن ممكن تواجه مشاكل في توجيه الاتصال خصوصا لو استخدمت WSL2, فالافضل تستخدم اوبونتو على جهاز افتراضي vm, المهم يكون عندك نظام linux وسطر اوامر وانترنت.

الشرح هنا بيكون على سيرفري الصغير وبستخدم سطر الاوامر بدون واجهة رسومية حتى تقدر تطبق هذا الشرح على اي نظام او توزيعة.

الشرح بيعتمد كلياً على حاويات دوكر docker و بيكون بهذا الترتيب

  1. تثبيت و تشغيل التطبيق. (وزي ماقلت قبل, ممكن يكون هذا التطبيق برمجة خاصة انت سويته وممكن يكون تطبيق جاهز مثلا مدونة wordpress او تخزين سحابي nextcloud.)
  2. انشاء dynamic DNS (او نطاق خاص) و اعداد Reverse proxy لتوجيه الاتصال.

تثبيت و تشغيل التطبيق

راح اعمل مثالين الاول تطبيق خاص بلغة python و الثاني تثبيت تطبيق جاهز Nextcloud. وفي البداية في متطلب نحتاج نسويه وهو تحديد او إنشاء مجلد خاص بكل تطبيق ليرتبط به ويتم فيه حفظ الاعدادت الخاصة بكل تطبيق, والربط بيكون باستخدام الـ volume في دوكر, ولازم تعرف IP الجهاز الي تسخدمه (internal ip) وفي هذا الموضوع بيكون الاي بي 192.168.1.145

نبدأ بانشاء مجلد ولنفترض اسمه myapps وهذا بيكون مجلد رئيسي و ثم ننشيء بداخلة مجلد خاص بكل تطبيق نعمله.

#make main dir
mkdir ~/myapps

#make dir for python app
mkdir ~/myapps/pythonapp

#make dir for nextcloud app
mkdir ~/myapps/nextcloud

#make dir for nextcloud app config
mkdir ~/myapps/nextcloud/config

• تثبيت وتشغيل تطبيق خاص بلغة python

توضيح: هذه ليست افضل طريقة لتشغيل تطبيق خاص داخل حاوية دوكر ولكنها مناسبة كبداية ولتوضيح الية عمل الحاوية. الطريقة الافضل بناء image مع الاعتماديات الخاصه بتطبيقك واعداد التشغيل التلقائي للتطبيق عند إعادة التشغيل.

لنفترض انك برمجت هذا التطبيق الرائع ببايثون flask

from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
    return 'such a good app to be self-hosted :)'

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

طيب الان نظيف الكود في ملف داخل المجلد الخاص بالتطبيق والي هو ~/myapps/pythonapp

(انشي ملف جديد وضيف الكود بأي طريقة تحبها حتى لو من خلال متصفح الملفات وواجهة سطح المكتب)

انا راح استخدم vim في انشاء وتعديل الملفات.. ونبدا بهذا الامر

#create new .py file
vi ~/myapps/pythonapp/pythonCode.py

الصق محتوى الكود واخرج بالضغط على shift + ZZ (شفت ودبل z)

الان ننشي حاوية جديدة فارغة بنظام ubuntu بهذا الامر

docker run -d --name myPythonApplication -v ~/myapps/pythonapp/:/pythonapp -p 5000:5000 ubuntu

الامر السابق يحتاج وقت بسيط لتنزيل الحاوية وراح تشتغل في الخلفية, لاحظ مسار ربط مجلد التطبيق في الحاوية، و معناه كودنا راح يكون داخل الحاوية في مجلد pythonapp مباشرة, واعرف البورت الي تستخدمه انا هنا استخدمت 5000

بعد الانتهاء من تشغيل الحاوية نتصل بها من خلال الامر التالي

docker exec -it myPythonApplication bash

الان نبدأ بتنفيذ عدة اوامر داخل الحاوية لتحديث وتثبيت الملفات الاساسية لتشغيل التطبيق

#update repos
apt update

#install python & flask
apt install python3 python3-flask

#export EV
export FLASK_APP=pythonCode.py

الان نروح لمجلد التطبيق داخل الحاوية ونشغل التطبيق بالامر التالي

#goto app dir
cd /pythonapp

#run the application
flask run --host=0.0.0.0

الان لو نرجع للمتصفح ونفتح الرابط بالاي بي بنشوف التطبيق شغال http://192.168.1.145:5000

my python app

• تثبيت وتشغيل تطبيق Nextcloud

بما ان هذا التطبيق جاهز فما نحتاج شغل كثير مجرد امر واحد لتشغيل الحاوية , نحتاج فقط نحدد موقع المجلد و الاعدادات الي نبيها في نفس الامر 👍🏻

docker run -d --name=nextcloud -p 32600:443 -v ~/myapps/nextcloud/:/data -v /~/myapps/nextcloud/config/:/config --restart unless-stopped  linuxserver/nextcloud

الاعدادت المهمة هنا البورت الي تستخدمه، هنا استخدمت 32600 ولازم تعرف المجلدات الي ربطناها

هنا ربطنا مجلدين

  1. الاول مجلد لاعدادت التطبيق config
  2. والثاني مجلد بيكون المكان الي نخزن فيه الملفات وقت استخدام التطبيق.

بس هذا الي تحتاجه مع دوكر :))

الان نفتح الرابط http://192.168.1.145:32600 وبنشوف صفحة التطبيق الرئيسية.

تقدر الحين تستخدم التطبيقات الخاصة فيك من داخل الشبكة زي ماتحب, واذا تبي تستخدم نطاق او رابط سريع للوصول للتطبيقات من خارج الشبكة فتحتاج سيرفر Reverse proxy او وكيل عكسي


تثبيت واعداد Nginx Reverse Proxy

Nginx وهو سيرفر ويب لتشغيل المواقع ويمكن استخدامه كـ reverse proxy.

• ماذا نعني بـ Reverse Proxy

الوكيل العكسي او reverse proxy هو سيرفر (برنامج) يكون هو الواجهه لاستقبال الاتصال او الطلبات ومن ثم يقوم بتوجيه الاتصال للتطبيق المرغوب.

• ما الفائدة من Reverse Proxy

له عدة استخدامات اهمها توجيه الاتصال, وبكل بساطة لو عندك تطبيقين او موقعين وبتشغلهم من مكان واحد تستخدم الوكيل العكسي, وثم وقت الاتصال والطلب تقوله ابي التطبيق الاول يوديك للتطبيق الاول .. او تبي التطبيق الثاني يوديك التطبيق الثاني.

مثال لو عندك بريد mail و مدونة blog وتبي تشغلها على نطاق (domain) واحد الي هو site.com .. يصير تقسم النطاق كالتالي

  1. للذهاب للبريد تطلب mail.site.com
  2. للذهاب للمدونة blog.site.com

والوكيل العكسي (reverse proxy) هو الي يتحكم في الطلب ويوديك للتطبيق المطلوب من خلال الاسم الاول في النطاق

• كيفية تشغيل Nginx Reverse proxy

راح نستخدم حاوية دوكر اسمها SWAG جاهزة باعدادتها للوكيل العكسي (شايف كيف روعة دوكر 💙)

تحتاج امتلاك نطاق (domain) لكن لأن النطاقات مدفوعة راح نستبدله بشي اسهل ومجاني هو dynamic DNS

• انشاء DDNS على موقع duckdns.org

موقع مجاني وسهل, سجل فيه واعمل DDNS خاص فيك بيكون شكله تقريبا كذا XXXXX.duckdns.org

duckdns

بعد ماتسوي الدومين اضغط على update بالاصفر , وخزن الـ token عندك وهو الرقم الطويل فوق. في الصورة انا انشأت لي هذا النطاق r1sknt.duckdns.org وراح نستخدمة في باقي الشرح.

• تشغيل الوكيل العكسي SWAG

قبل البدء لازم تفتح البورت 443 والطريقة تعتمد على الراوتر او المودم الي عندك وهي فتح البورت 443 وتوجيهه لبورت الوكيل العكسي 32443 مع اي بي الجهاز والي كان في هذا الشرح 192.168.1.145 , ابحث في قوقل عن الطريقة لنوع المودم عندك. 🌚

تشغيل الوكيل العكسي من حاوية SWAG سهل جداً , ننفذ الامر التالي

docker run  -d  --name=swag  -e URL=r1sknt.duckdns.org  -e SUBDOMAINS=wildcard  -e VALIDATION=duckdns  -e DUCKDNSTOKEN=YOUR-TOKEN-HERE  -p 32443:443 --restart unless-stopped  linuxserver/swag

لاحظ النطاق في المتغير URL ورقم التوكن في المتغير DUCKDNSTOKEN لازم تضيف البيانات الخاصة بحسابك الي خزنتها وقت انشاء النطاق في موقع duckdns.org, واعرف البورت الي تستخدمه زي هنا استخدمت 32443

الان بعد تشغيل الحاوية نحتاج نتصل فيها وننشي ملفين, ملف خاص بكل تطبيق ثبتناه فيكون عندنا

  1. ملف بإسم pythonapp.subdomain.conf خاص بتطبيقنا الي برمجناه بالبايثون
  2. ملف بإسم nextcloud.subdomain.conf خاص بتطبيق nextcloud

الان نتصل بالحاوية بهذا الامر

docker exec -it swag bash

ونذهب لمسار الاعدادت و ننشي الملف الاول pythonapp.subdomain.conf كالتالي

#goto conf dir
cd /config/nginx/proxy-confs

#craete new file pythonapp.subdomain.conf
vi pythonapp.subdomain.conf

ونلصق هذا المحتوى في الملف

server {
listen 443 ssl;
listen [::]:443 ssl;
server_name pythonapp.*;#غير اسم التطبيق هنا  تأكد من وجود النقطة والنجمة بعده
include /config/nginx/ssl.conf;
client_max_body_size 0;
location / { include /config/nginx/proxy.conf;
resolver 127.0.0.11 valid=30s;
set $upstream_app nextcloud;
set $upstream_port 443;
set $upstream_proto https;
proxy_pass $upstream_proto://192.168.1.145:5000; #لاحظ هنا اي بي الجهاز مع البورت الخاص بالتطبيق
proxy_max_temp_file_size 2048m;
}}

ونخرج ب shift + ZZ

ونكرر الخطوات وننشي ملف ثاني باسم nextcloud.subdomain.conf ونلصق فيه نفس المحتوى بالاعلى مع تغيير البورت ل 32600 وهو البورت الي شغلنا عليه تطبيق nextcloud

الان نعيد تشغيل حاوية الوكيل العكسي لاستخدام الملفات الاخيرة, بالامر التالي

docker restart swag

وبعد تطبيق الشرح لو نتوجه للرابط pythonapp.r1sknt.duckdns.org بيفتح تطبيق البايثون وبتلاحظ كمان ان الاتصال مشفر وعلامة القفل بجانب النطاق (التشفير هنا احدى خصائص الحاوية swag) وكمان لو نفتح الرابط nextcloud.r1sknt.duckdns.org بيفتح التطبيق معنا ويكون جاهز للاستخدام.

nextcloud setup

الخطوة الاخيرة وهي تثبيت الاي بي (وهنا نقصد الاي بي الخارجي مو نفس الي استخدمناه في الشرح) , في اي راوتر او مودم راح يتيغر الاي بي مرة او حتى 20 مرة في اليوم بشكل طبيعي وهذا الاي بي لازم يكون مربوط بالنطاق او ddns تبعك, لو ترجع لموقع duckdns بتلاقي خانة تحط فيها الاي بي وتعمل تحديث, ولكن مو معقول تعمل عشرات التحديثات للاي بي في اليوم.

طرق تثبيت الاي بي او تحديثه تلقائيا متعددة وتعتمد على مقدم الخدمة ddns الي تستخدمه. افضل طريقة لتثبيت الاي بي لشرحنا هذا بسيطة وهي تشغيل حاوية جديدة duckdns وتعطيها التوكن حق حسابك في الموقع وهي تعمل التحديث, حاول تعملها بنفسك. بسيطة جدا 😉

خاتمة

في هذا الموضوع استخدمت طريقة سهلة جدا للبدء في self hosting، لكن قد تكون فائدة العمل محدود لو تم التطبيق على جهاز لابتوب او مكتبي، لكن لو تحب تبدأ فعليا تقدر تشتري جهاز raspberry pi وهذا كافي جدا انه يخدمك على مدار الساعه وباستهلاك طاقه بسيط جدا، ويعتبر مدخل ممتاز لعالم الـ homelab او بناء لاب منزلي يختص بالشبكات والانظمة الافتراضية والبرمجة.

واخيراً، سبحان الله وبحمده سبحان الله العظيم.

Example Ad #2 (only visible for logged-in visitors)