البحث في الموقع
المحتوى عن 'deployment'.
-
قليلة هي تلك المشاريع والابتكارات التي تُحدِث نقلة نوعية في عالم البرمجيات والتقنية بشكل عام، وإن كنا سنشهد في هذه العشرية إحدى هذه المشاريع، فهو Docker بامتياز. فما هو Docker هذا؟ هذا المقال يهدف بشكل خاص إلى التعريف بمشروع Docker والفكرة التي جاء بها، وليس لكيفية البدء به (والتي ستكون في مقال منفصل إن شاء الله)، حيث لا يمكن البدء به إذا لم نفهم فكرته وأهميته في عالم البرمجيات. لمن هذا المقال؟لمدراء الخواديم (SysAdmins) بالدرجة الأولىللمبرمجين ومطوري الويب بالدرجة الثانية قبل أن نتحدث عن ماهية Docker أحب أولا ذكر أهم 03 مشاكل نواجهها حاليا كمطورين ومدراء خواديم والتي يحاول Docker معالجتها... 1. جحيم الاعتماديات (the dependecy hell)الأغلبية الساحقة من مشاريع الويب "الجدية" والكبيرة لا تكون قائمة بذاتها، بل هي عبارة عن مكتبات تتواصل فيما بينها أو تعتمد على مكتبات أخرى من أجل أن تعمل، مطوروا Ruby، Python وحتى node.js و php يفهمون ذلك جيدا، وكل من هذه اللغات حاول حل المشكلة على نطاقه الخاص عبر إنشاء أدوات مساعدة تعرف بـ"مدراء الاعتماديات" أو "مدراء حزم" (dependency/package managers) أمثلة ذلك: pip بالنسبة لبايثونgem بالنسبة لروبيnpm بالنسبة لـ node.jsوأخيرا محاولة متواضعة من php عبر composer..وقد تذهب اللغة إلى أبعد من ذلك مثل ما فعلت بايثون بإنشاء بيئات وهمية تعزل فيها المكتبات والاعتماديات مثل مشروع virtualenv. كل من هذه اللغات تستعمل مدراء الاعتماديات/الحزم لجلب وإدارة المكتبات الخارجية التي يعتمد عليها المشروع (third party librairies)، لكن السؤال هنا، إذا كانت هذه اللغات وفرت هذه الأدوات، فأين المشكل؟ في الحيقيقة بالرغم من توفر هذه الأدوات، تبقى هناك مشاكل عالقة دائما خاصة على مستوى تنصيب المشروع على الخواديم (deployment) من ذلك: كثرة الاعتماديات، مما يأخذ وقتا في التنزيل، وأحيانا لا توجد تلك الاعتمادية على منصة الخادوم البعيد وقد تحتاج إلى عمل تجميع يدوي لها، وهذا يجعل الأمر مُتعبا.اعتمادية تعتمد في حد ذاتها على اعتمادية أخرى، قد تكون مثلا تشترط منصة Java بأكملها، وقد تكون أيضا هذه الأخيرة تعتمد على اعتماديات أخرى وهكذا...تعارض الاعتماديات، وجود إحداها يتطلب غياب الأخرى واستحالة عملهما معا في نفس الوقتنسخة الاعتمادية التي تم تنزيلها مغايرة للتي تم تطوير المشروع بها. والنسخة الجديدة تأتي بتغيرات غير متوافقة رجعيا (API backward compatibility)كل هذه المشاكل وغيرها، تجعل من ناقلية المشروع من مكان إلى آخر أو من خادوم إلى آخر، عملية شاقّة. 2. صعوبة نشر، تنصيب، نقل مشاريع الويبمشاريع الويب الكبيرة تحتاج إلى عدد من الاحتياطات: متغيرات بيئة (environment variables) يجب تعيينها مسبقاإعداد لنظام الـ cacheإعداد للخادوم nginx أو غيرهإعدادات أمنيةتحديث النظام وبرمجياته قد يسبب عطلا ما للمشروع،...ماذا عن نقل المشروع من خادوم إلى آخر؟ أو في حالة وجود أكثر من خادوم... وكل منه له نظامه الخاص (من CentOs إلى Ubuntu مثلا أو حتى BSD).... 3. التطوير، التسليم والزرع المتواصل للمشاريع ( continuous delivery/integration)مشاريع الويب الجدية تتبع دورة تطوير معينة، تحسين دائم، إدخال لميزات جديدة بشكل دوري، قفل للثغرات ... إلخ، بعد هذا يجب إجراء سلسلة من الفحوصات (unit tests مثلا) للتأكد من سلامة المشروع وأنه أهل للمرحلة الإنتاجية منه (production ready)، كل هذا سهل محليا،... لكن عملية إبقاء جميع الخواديم مسايرة لوتيرة التطوير هذه أمر شاق ومتعب، خاصة حينما نحتاج إلى تحديث الاعتماديات أو وجود إعتماديات جديدة وبالتالي احتياطات جديدة... هذه المشاكل ليس حصرا، فهناك غيرها من المشاكلة الأمنية (مثال ثغرة في مشروع الويب تمكن المخترق من الوصول إلى النظام)، مشاكل عزل (قاعدة البيانات في نفس بيئة التطبيق نفسه مما قد يسمح للوصول السهل لها من قبل المخترق)، مشاكل نسخ اختياطي (backups)،.. الخ إذا ما هو Docker؟Docker عبارة عن أداة جديدة تستغل ميزات الإصدارات الأخيرة من نواة Linux الخاصة بعزل المهام والعمليات (processes)، عمليات الإدخال والإخراج (i/o)، حجز الذاكرة وتحديدها، صلاحيات القراءة والكتابة للقرص الصلب... وغير ذلك، في إنشاء حاويات (containers) ركز على هذه الكلمة جيدا، حيث أن هذه الحاويات تلعب دور غلاف حاوي لتطبيق ما (مشروع ويب مثلا)، بحيث يصبح قائما بذاته، مكتفٍ ذاتيا. أي أن مشروع الويب وكامل الاعتماديات التي يحتاجها ليعمل + التوزيعة المناسبة له (Fedora, Ubuntu.. الخ) بجميع التهيئات ومتغيرات البيئة التي يحتاجها، كل هذا في حاوية (قد تكون حاوية واحدة أو عدة حاويات تتخاطب في ما بينها عملا بمبدأ "عزل الاهتمامات" SoC). لتقريب الصورة، تخيل أنه باستعمال Docker يمكنك عمل التالي: طورت تطبيقك على Ubuntu أو تعلم أنه يعمل بشكل جيد على توزيعة Ubuntu وبالتحديد الإصدارة 14.04 منها، وبالتالي تقول لـ Docker استعمل نسخة Ubuntu 14.04 (يتكفل هو بتزيل الصورة الخام من Ubuntu 14.04 - حوالي 60 إلى 300 Mb تقريبا- واستعمالها كتوزيعة للحاوية)مشروع الويب خاصتي يستعمل Python وبالتحديد النسخة 2.7 منها، ويعمل بشكل جيد على هذه النسخة، لم أجرب على Python 3، تقول لـ Docker نصب Python2.7 في الحاوية التي بها نظام Ubuntu 14.04 الذي سبق تنزيل صورته الخاممشروع الويب خاصتي يستعمل مكتبة Flask أو Django و مكتبة Numpy الخاصة ببايثون، يتم تثبيتهم عبر pip وبالتالي تقول لـ Docker نصب لي على الحاوية التي بها Ubuntu 14.04 و Python 2.7 السابقة تطبيق Pip عبر مدير حزم Ubuntu (أي apt-get install python-pip) ثم باستعمال pip نصب لي مكتاب بايثون السابق ذكرهامشروع الويب الخاص بي يحتاج قاعدة بيانات MySQL، نصبها يا Docker عبر مدير حزم Ubuntuأيضا نحتاج nginx أو apache، كذلك تطلب من Docker أن ينصبه عبر مدير حزم Ubuntuاجمع لي كل هذا في صورة واحدة (image) يمكن تشغيلها على أي خادوم أو حاسوب به Docker عبر الأمر: docker run my_imageجميع هذه الخطوات يمكن أتمتتها وسردها في ملف واحد اسمه DockerFile، كل سطر من هذا الملف عبارة عن أمر لـ Docker يقوم به (تماما كما قمنا به أعلاه)، مجموع الأوامر يكون الخطوات التي يمر بها Docker لبناء الحاوية التي نريدها، في ما يلي مثال عن ملف DockerFile: FROM ubuntu 14.04 # Install Python RUN apt-get install -y python-dev # Install pip RUN apt-get install -y python-pip # Install requirements.txt ADD requirements.txt /src/requirements.txt RUN cd /src; pip install -r requirements.txt # Add the Flask App ADD . /src # EXPOSE PORT EXPOSE 80 # Run the Flask APP CMD python src/app.pyيمكن حفظ هذه الأوامر في ملف باسم Dockerfile، يمكنك أيضا تشغيل هذا الملف لبناء صورة (image) لحاوية container من خلال Docker عبر الأمر التالي: docker build -t <your username>/my-flask-app .لاحظ النقطة في آخر الأمر، والتي تعني "استعمل ملف DockerFile الموجود في المجلد الحالي"، أما تعليمة t- بعد أمر build هي لاعطاء وسم (tag) للحاوية التي نريد بناءها. عادة من المتعارف عليه هو اعطاء اسم مستخدمك يليه "/" يليه اسم تطبيقك. مفهوم الحاويات (Containers)الحاوية في Linux عبارة عن غلاف يطبّق مجموعات من القيود لعزل عملية أو مجموعة عمليات (processes) عن باقي مهام وعمليات النظام من ناحية السياق (context)، الذاكرة RAM، القراءة والكتابة، الشابكة (Network)... الخ، بحيث تكون في معزل تام عن باقي الـ processes في النظام. أي نفس فكرة الـ sandboxing. مفهوم الحاويات ليس جديدا، فقد بدأ بالظهور منذ أواخر عام 2007، حين عرض مهندسون لدى Google مشروع cgroups (اختصارا لـ Control Groups) ليتم دمجه في نواة Linux، منذ ذلك الوقت cgroups كان اللبنة الأساسية لعزل الموارد وكبحها في نظام Linux على مستوى النواة. بعدها جاء مشروع LXC (اختصارا لـ LinuX Containers) والذي جمع بين cgroups وميزة عزل نطاقات الأسماء (namespace isolation) في نواة Linux، لتوفير إمكانية إنشاء مجموعات منفصلة عن بعضها من العمليات (process groups)، كل مجموعة مكتفية ذاتيا و/أو محدودة المواد، بحيث لا تدري كل مجموعة عن الأخرى بالرغم من أنهم يشاركون نفس النواة (نواة Linux). هذه المجموعات عُرفت باسم الحاويات Containers. على الرغم من أن LXC الأقرب لفكرة Docker، إلا أنه بقي على مستوى منخفض ولم يوفر واجهة برمجية سهلة للمطورين مثل ما قدمه Docker. إضافات Dockerفي أيامه الأولى، اعتمد مشروع Docker على LXC وبنى عليه، أي استعمله كـ backend أو driver، (لكن الآن يمكن استعمال بدائل لـ LXC) لكنه أضاف عدة أمور عصرية، بعضها مستوحى من أنظمة إدارة النسخ (Version Control Systems) من ذلك: مفهوم Docker image لبناء لقطات من الحاويات (نفس فكرة ملفات .iso) يمكن تصديرها واسترادها، وبالتالي يمكن بناء صورة للمشروع بأكمله ثم يكفي استراد تلك الصورة على الخاودم، يتوجب فقط أن يكون Docker مُنصّبا.إمكانية عمل "إيداع" (Commit) للتغيرات التي قمت بها على صورة المشروع الخاص بك، وبالتالي إمكانية الرجوع للوراء في حال الخطأ، هذه الميزة تسمح أيضا لـ Docker أن يكون وسيلة حفظ احتياطي "backup".كل صورة بنيتها يمكنك مشاركتها مع المجتمع في فهرس docker، والذي كان اسمه Docker index ثم تحول مؤخرا إلى docker hub. ستجد فيه مثلا صور لـتطبيق WordPress منصبة على Ubuntu جاهزة للاستهلاك المباشر، أليس هذا رائعا؟مفهوم الـ Dockerfile الذي سبق عرض ماهيته، وهو وسيلة لأتمتة وسرد خطوات بناء مشروعك أو حاويتك. الأتمتة التي تتيحها ملفات Dockerfiles تسمح بانتهاج نسق Continuous integration الذي تكلمنا عنه، تخيل أنك تريد تجربة مشروعك على Python 3 مثلا، كل ما عليك هو تغيير نسخة Python في ملف Dockerfile وبناء حاوية جديدة لتجرب عليها الناتج، فإن كان جيدا تدفعه للخادوم، وإن لم يكن كذلك تحذفه. نفس الشيء مع إصدارات المكتبات التي يعتمد عليها مشروعك.هذه بعض مما أضافه Docker لما هو موجود، وهي وحدها كفيلة بإحداث قفزة وتحول نوعي في طريقتنا لبناء ونشر البرامج. لكن السؤال الذي قد يطرحه البعض: أليس ما يعمله Docker هو نفسه ما تعمله الآلات الافتراضية Virtual Machines ومحاكاة الأنظمة؟ باختصار، نعم ولا وسنلخص الأمر في النقاط التالية: Docker أخف بكثير من الآلات الافتراضية، يمكنك تشغيل العشرات من الحاويات في حاسوب عادي واحد، في حين لا يمكنك تشغيل 3-4 آلات افتراضية في حاسوب عادي واحد ولو كان قويا نسبيا (يثقل النظام). أي أن Docker يستهلك موارد أقل بكثير.الآلات الافتراضية تقوم بمحاكاة كـــامــل النظام وكل ما فيه ووضعه فوق النظام المضيف، في حين Docker يتشارك النواة (Linux kernel) مع النظام المضيف.ما يقوم به Docker هو تنزيل التوزيعات فقط، أي الـ bins/libs لكل توزيعة وفقط، في حين يتشارك النواة مع النظام المضيف ولا يُنزّل نواة جديدة مع تلك التوزيعة. تلك الـ bins/libs كفيلة لمحاكاة بيئة التوزيعة المرجوة، أما النواة فهي متشابهة بين جميع التوزيعات وبالتالي يتقاسمها مع النظام المضيف (لهذا Docker لا يعمل إلا على Linux).Docker يعزل التطبيق واعتمادياته فقط، في حين الآلات الافتراضية تعزل كامل النظام وما فيه من تطبيقات.الصورتان التاليتان توضحان الفرق بين Docker والآلات الافتراضية: من خلال الصورتين يمكن ملاحظة أن وزن Docker على الخادوم بشكل عام أخف بكثير من الثقل الذي تحدثه الآلات الافتراضية. الجدير بالذكر أيضا أن القائمين على مشروع Docker قاموا بتوفير ما يسمى بـ Docker Hub، يمكن فيه مشاركة صور (images) لمشروعك (إن كان مفتوح المصدر)، تجد فيه صورا للحلول مفتوحة المصدر المعروفة، كصور Wordpress, joomla, mysql, nginx .. الخ، بحيث يمكنك استهلاكها مباشرة أو استيرادها والبناء عليها أدعوك ﻷن تلقي عليه نظرة. يمكن أيضا أن تكون مستودعا خاصا لك، لمشاريعك التجارية غير مفتوحة المصدر / مجانية، تجلب منه وتسترد صورك الخاصة التي قمت ببنائها. إلى هنا نصل إلى خاتمة هذه المقدمة التعريفية. سنقوم في مقال لاحق إن شاء الله بشرح أساسيات Docker بشكل عملي. إذا كانت لغتك الانجليزية جيدة، فأنصحك بمشاهدة الفيديو التالية لفهم أعمق للمقال:
- 18 تعليقات
-
- 2
-
- deployment
- containers
-
(و 2 أكثر)
موسوم في:
-
اشتهر استخدام منصة Heroku السحابية ضمن مجتمع مطوري Ruby on Rails ونالت فيه شعبية واسعة؛ إلا أن الخدمة لم تقتصر على مطوري Ruby وما يدور حولها بل تجاوزتهم إلى تقديم الدعم للغات برمجة مثل Node.js ،Java و PHP؛ من بين أخرى. توفّر Heroku خطّة اشتراك مجانية يمكن استخدامها لإدارة مشاريع صغيرة جدا أو لأغراض الاختبار. سنشرح في هذا الدرس كيفية الاستفادة من Heroku عبر هذه الخطة لنشر Deploying تطبيقات Laravel. إنشاء حساب على Heroku يجب أولا أن ننشئ حسابا على موقع الخدمة حتى يمكننا الاستفادة منها. التسجيل مجاني ولا يستغرق سوى دقائق. ستُعرَض عليك خلال عملية التسجيل خيارات للغة البرمجة التي تريد استخدامها، اختر PHP؛ مع العلم أن هذا الخيار لا يؤثّر على إمكانية استعمالك للغات برمجة أخرى مستقبلا. تثبيت Heroku Toolbelt الخطوة الثانية بعد إنشاء الحساب هي تثبيت أداة Heroku Toolbelt. تُستخدَم هذه الأداة، التي تعمل عبر سطر الأوامر، لإدارة جوانب عدّة من المشاريع المضافة إلى Heroku؛ ومن ضمنها إدارة عمليّة النشر، تهجير Migrating قاعدة البيانات والتخاطب مع خادوم Heroku. تتوفّر الأداة على وندوز، ماك وتوزيعة أوبونتو لينكس. نفّذ بعد تثبيت الأداة الأمر التالي: $ heroku login heroku-cli: Installing CLI... 21.83MB/21.83MB Enter your Heroku credentials. Email: mail@example.com Password (typing will be hidden): Logged in as mail@example.com انتظر قليلا حتى يكتمل تنزيل عميل Heroku ثمّ أدخل معلومات الاستيثاق الخاصّة بك (عنوان البريد وكلمة السر). نشر تطبيق Laravel على Heroku يمكننا الآن بعد التسجيل في Heroku وتثبيت الأداة Heroku Toolbelt نشرُ مشروع Laravel. نبدأ بإنشاء مشروع Laravel جديد (على الحاسوب الشخصي): $ composer create-project laravel/laravel dev.herokutest.com dev-develop Installing laravel/laravel (dev-develop 083db95...dac46617) - Installing laravel/laravel (dev-develop develop) Cloning develop ... Compiling views Do you want to remove the existing VCS (.git, .svn..) history? [Y,n]? Y Application key [9UCBk7IDjvAGrkLOUBXw43yYKlymlqE3Y] set successfully. ثم ننشئ ملفا باسم Procfile ونضعه في المجلد الجذر لمشروع Laravel. طريقة كتابة اسم الملفّ مهمة جدا (الحرف الأول كبير، ولا وجود لامتداد للملف). يقرأ Heroku هذا الملفّ لتحديد نوع العمليات التي سيجريها بعد نشر التطبيق. في حالة تطبيق Laravel فإن نوع العمليات المطلوب هو وِب web. نحدّد نوع خادوم الوِب المستخدم لتقديم التطبيق (Apache) والمجلّد الذي توجد به ملفات التطبيق المخصّصة للعرض، وهو في حالة Laravel المجلد public. يصبح ملفّ Procfile على النحو التالي: web: vendor/bin/heroku-php-apache2 public هذا فقط مثال على الخيارات المتاحة، يمكنك تغيير هذه الخيارات (خادوم الوِب مثلا) إن أردت ذلك. الخطوة الموالية لإنشاء ملفّ Procfile هي وضع المشروع تحت تصرّف نظام إدارة الإصدارات Git بإنشاء مستودع للمشروع: $ git init Initialized empty Git repository in /home/zeine77/dev.herokutest.com/.git/ $ git add . $ git commit -m "First commit" يسهّل استخدامُ Git كثيرا عمليةَ النشر، فإطار العمل Laravel يأتي مبدئيا بميزات خاصّة بنظام إدارة الإصدارات Git (مثل ملفات gitignore.)؛ كما أن Heroku أيضا يتفاعل مع مستودع Git المحلي لتسهيل النشر. راجع هذه المقالات لمعرفة المزيد عن Git. نحن الآن جاهزون لنشر التطبيق على Heroku. نستخدم Heroku Toolbelt لهذه المهمة: $ heroku create Heroku CLI submits usage information back to Heroku. If you would like to disable this, set `skip_analytics: true` in /home/zeine77/.heroku/config.json Creating app... done, ⬢ nameless-chamber-90421 https://nameless-chamber-90421.herokuapp.com/ | https://git.heroku.com/nameless-chamber-90421.git ينشئ الأمر heroku create اسما جديدا لمشروعك (أعطاني الاسم nameless-chamber-90421) ويعرّف رابطا يمكن عبره الوصول إلى التطبيق. لا يوجد على الرابط - لحد السّاعة - سوى صفحة مبدئية من Heroku. زيادة على الرابط والاسم، أنشأ الأمر السابق مستودع Git بعيدا. مستودع Git بعيد هو مستودع يضم ملفات مشروعك ولكنه يوجد في مكان آخر غير جهازك؛ يمكن دفع التغييرات إلى المشروع البعيد أو جلبها منه. سنكتفي في حالة Heroku بدفع التعديلات إلى المستودع البعيد، كما سنرى بعد قليل. يستخدم Heroku ملفات تسمى buildpacks (حزم بناء) لمعرفة البرامج التي يجب عليه إعدادها على الخادوم بعد تثبيت التطبيق؛ لذا يجب أن نحدّد واحدا. اخترنا ملفّ buildpack الرسمي من Heroku الخاص بتطبيقات PHP؛ نستخدم الأمر config:add في Heroku Toolbelt لتحديد هذا الملف: $ heroku config:add BUILDPACK_URL=https://github.com/heroku/heroku-buildpack-php Setting BUILDPACK_URL and restarting ⬢ nameless-chamber-90421... done, v3 BUILDPACK_URL: https://github.com/heroku/heroku-buildpack-php تستخدم تطبيقات Laravel مفتاح تعميّة Encryption key لتعمية معلومات جلسة المستخدم ومعلومات أخرى؛ توجد قيمة هذا المفتاح في متغيّر البيئة APP_KEY. يوجد المتغيّر APP_KEY في الملفّ env.، إلا أن الملف env. لا يدخل في إطار الملفات التي يتعامل معها Git، نظرا لوجوده في الملفات المحدّدة في gitignore.. سنحتاج إذن لتوليد مفتاح تعميّة لاستخدامه على خادوم Heroku. تُستخدم أداة artisan لتوليد مفتاح تعمية على النحو التالي: php artisan key:generate --show يولّد الأمر أعلاه مفتاح تعميّة ويعرضه على سطر الأوامر؛ إلا أننا نريد أن نخزّن المفتاح على الخادوم؛ نستخدم Toolbelt لهذا الغرض على النحو التالي: heroku config:set APP_KEY=$(php artisan --no-ansi key:generate --show) Setting APP_KEY and restarting ⬢ nameless-chamber-90421... done, v7 APP_KEY: base64:jp40IC7SV5eJ5IhjQYwqk/KXJG0uS+ZhCqSGwkwgELs= يضبط الأمر السابق قيمة المتغيّر APP_KEY على الخادوم لتساوي نتيجة تنفيذ الأمر php artisan --no-ansi key:generate --show. حان الآن وقت النشر فعليا؛ ندفع التغييرات في المستودع المحلي إلى المستودع البعيد باستخدام Git على النحو التالي: $ git push heroku master Counting objects: 103, done. Delta compression using up to 4 threads. Compressing objects: 100% (84/84), done. Writing objects: 100% (103/103), 43.87 KiB | 0 bytes/s, done. Total 103 (delta 5), reused 0 (delta 0) remote: Compressing source files... done. remote: Building source: remote: remote: -----> Fetching set buildpack https://github.com/heroku/heroku-buildpack-php... done remote: -----> PHP app detected remote: remote: ! WARNING: Your 'composer.json' contains a non-'stable' setting remote: for 'minimum-stability'. This may cause the installation of remote: unstable versions of runtimes and extensions during this deploy. remote: It is recommended that you always use stability flags instead, remote: even if you have 'prefer-stable' enabled. For more information, remote: see https://getcomposer.org/doc/01-basic-usage.md#stability remote: remote: -----> Bootstrapping... remote: -----> Installing platform packages... remote: - php (7.0.7) remote: - ext-mbstring (bundled with php) remote: - apache (2.4.20) remote: - nginx (1.8.1) remote: -----> Installing dependencies. (...) remote: -----> Compressing... remote: Done: 15.5M remote: -----> Launching... remote: Released v4 remote: https://nameless-chamber-90421.herokuapp.com/ deployed to Heroku remote: remote: Verifying deploy... done. To https://git.heroku.com/nameless-chamber-90421.git * [new branch] master -> master إن نظرت إلى لوحة التحكّم في Heroku ستجد سجلا بالإجراءات السابقة. هذا كلّ ما في الأمر؛ اكتمل نشرُ تطبيقك الآن ويمكنك الوصول إليه على الرابط المذكور أعلاه. يجب أن تظهر صفحة Laravel المبدئية. تذكّر أن الرابط المنشَأ سابقا موجود فقط لأغراض الاختبار والتجربة، عندما يكون تطبيقك جاهزا لتلقي الجماهير يمكنك استخدام نطاقك الخاص وربطه بالتطبيق. تهجير قاعدة البيانات نشرنا في الخطوات السابقة تطبيق Laravel جديدا؛ إلا أن هذه الخطوات لن تكون كافية إن كان التطبيق يعتمد على قاعدة بيانات. ستحتاج في هذه الحالة إلى التأكد من تنفيذ جميع التهجيرات العالقة بعد كلّ عملية نشر. بما أن التطبيق جديد على Heroku فسنحتاج لتموين Provision قاعدة البيانات؛ نستخدم Toolbelt لهذا الغرض: $ heroku addons:create heroku-postgresql:hobby-dev Creating postgresql-rigid-59415... done, (free) Adding postgresql-rigid-59415 to nameless-chamber-90421... done Setting DATABASE_URL and restarting nameless-chamber-90421... done, v10 Database has been created and is available ! This database is empty. If upgrading, you can transfer ! data from another database with pg:copy Use `heroku addons:docs heroku-postgresql` to view documentation. ينشئ الأمر السابق قاعدة بيانات PostgreSQL معرّفة بالخطة المجانيّة hobby-dev التي تمكننا من إنشاء قاعدة بيانات مجانية على Heroku، على ألا يتجاوز عدد أسطرها العشرة آلاف. توجد خطط أخرى يمكن النظر فيها لإيجاد ما يناسبك إن كنت تريد استخدام Heroku بيئةً للإنتاج. يعود السبب في اختيارنا لقاعدة بيانات PostgreSQL بدلا من MySQL إلى أن دعم الأخيرة على Heroku محدود، ستجد لهذا السبب أن الكثير من التوثيق حول خدمة Heroku يعتمد على قاعدة البيانات PostgreSQL. ثم نفذ الأمر التالي للحصول على المزيد من التفاصيل عن قاعدة البيانات ومن ضمنها الاستيثاق (تأكد من اسم التطبيق): $ heroku config --app nameless-chamber-90421 | grep DATABASE_URL DATABASE_URL: postgres://USERNAME:PASSWORD@HOSTNAME:PORT/DATABASE يظهر في نتيجة الأمر اسمُ المستخدم USERNAME، كلمة السّر PASSWORD، اسم المضيف HOSTNAME، المنفذ PORT واسم قاعدة البيانات DATABASE. لن يكون ضروريا حفظ هذه الإعدادات فالمتغير DATABASE_URL الذي يخزّنها محفوظ تلقائيا في إعدادات الخادوم. يمكنك تسهيل إدارة قاعدتي البيانات على طرفيْ العمل (بيئة التطوير وبيئة الإنتاج) بضبط متغيّر بيئة باسم DATABASE_URL على جهازك المحلي وتخزين إعدادات قاعدة البيانات فيه ثم استخدامه لإعداد اتصال Laravel بقاعدة البيانات. ستحتاج لتثبيت PostgreSQL على جهازك إن لم يكن مثبتا مسبقا. يستعمل Laravel مبدئيا قاعدة بيانات MySQL، لذا يجب أن نعدّه لاستخدام PostgreSQL. نفتح ملفّ إعداد الاتصال بقاعدة البيانات config/database.php ونبحث عن السطر التالي: 'default' => env('DB_CONNECTION', 'mysql'), ثم نعدّله على النحو التالي: 'default' => env('DB_CONNECTION', 'pgsql'), ثم ننتقل إلى المقطع الخاصّ بإعداد PostgreSQL ضمن ملفّ إعداد الاتصال ونعدّله ليصبح كالتالي: 'pgsql' => [ 'driver' => 'pgsql', 'host' => parse_url(getenv("DATABASE_URL"))["host"], 'database' => substr(parse_url(getenv("DATABASE_URL"))["path"], 1), 'username' => parse_url(getenv("DATABASE_URL"))["user"], 'password' => parse_url(getenv("DATABASE_URL"))["pass"], 'charset' => 'utf8', 'prefix' => '', 'schema' => 'public', ], احفظ التعديلات ثم تأكد من أن اتصال التطبيق بقاعدة البيانات (محليّا)؛ يمكنك إنشاء نموذج في Laravel وتهجير مرافق له لغرض اختبار الاتصال بقاعدة البيانات. نفذ بعد التأكد من إعداد قاعدة البيانات التعديلات التي أضفتها إلى منطقة الإدارج في Git ثم أودعها في المستودع وأرسلها إلى المستودع البعيد على الخادوم: $ git add . $ git commit -m "Updated database configuration" $ git push heroku master يمكنك الآن تنفيذ التهجير على قاعدة البيانات على الخادوم عن طريق Toolbelt كالتالي: $ heroku run php artisan migrate --app nameless-chamber-90421 Running `php artisan migrate` attached to terminal... up, run.6981 ************************************** * Application In Production! * ************************************** Do you really wish to run this command? [y/N] y Migration table created successfully. Migrated: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_100000_create_password_resets_table Migrated: 2015_01_30_032004_create_todolists_table.php ترجمة -وبتصرّف- للمقال Deploying a Laravel Application to Heroku لصاحبه W. Jason Gilmore.
-
ستغطّي هذه السّلسلة عمليّة نشر تطبيق PHP بسيط باستخدام Ansible، الهدف النّهائي سيكون الحصول على خادوم ويب جديد يُخدِّم تطبيق PHP بسيط بدون أي اتصال عبر SSH أو تشغيل يدوي للأوامر على الخادوم الهدف، سنغطي في هذا القسم من الدرس تثبيت Ansible وإعداد البيئة بشكل عام. سنستخدم إطار عمل Laravel كمثال عن تطبيق PHP ولكن يُمكِن تعديل هذه التعليمات بسهولة لتدعم أطر عمل وتطبيقات أخرى في حال كانت متواجدة لديك. المتطلبات الأساسيةسنستخدم Ansible لتثبيت وإعداد Nginx، PHP، وخدمات أخرى على خادوم Ubuntu 14.04 ، يعتمد هذا الدّرس على معرفتك الأساسية بـ Ansible لذا إن كنت جديدًا عليها فبإمكانك قراءة درس Ansible الأساسي أولًا. ستحتاج لمتابعة هذا الدّرس إلى: خادوم Ubuntu 14.04 بأي حجم والذي سنستخدمه لإعداد ونشر تطبيق PHP الخاص بنا عليه، ستتم الإشارة إلى عنوان IP هذا الجهاز بـ your_server_ip خلال هذا الدّرس.خادوم Ubuntu 14.04 والذي سنستخدمه من أجل Ansible، وهو الخادوم الذي سنبقى في وضعية تسجيل دخول عليه في كامل هذا الدّرس.إعداد مستخدم غير جذري مع صلاحيّات sudo لكل خادوم.مفاتيح SSH من أجل خادوم Ansible لتصريح تسجيل الدخول على خادوم نشر PHP، ويُمكِن إعدادها باتّباع هذه السلسلة وتطبيقها على خادوم Ansible الخاص بنا.الخطوة الأولى – تثبيت Ansibleيُمكِن إنجاز هذه الخطوة بسهولة عن طريق تثبيت PPA (أرشيف الحِزَم الشخصي Personal Package Archive) وتثبيت حزمة Ansible باستخدام apt. نُضيف أوّلًا PPA باستخدام الأمر apt-add-repository: sudo apt-add-repository ppa:ansible/ansibleوبعد انتهائه نقوم بتحديث ذاكرة التخزين المؤقّت cache لـ apt: sudo apt-get update نقوم بتثبيت Ansible أخيرًا: sudo apt-get install ansibleحالما يتم تثبيت Ansible نقوم بإنشاء دليل جديد للعمل بداخله وضبط الإعدادات الأساسيّة، تستخدم Ansible افتراضيًّا ملف مضيفين hosts موجود في المسار etc/ansible/hosts/، وهو يحتوي كافّة الخواديم التي يُديرها، وبينما يكون هذا الملف مناسبًا لبعض حالات الاستخدام فهو عام global، وهو ما لا نريده هنا. سنقوم من أجل هذا الدّرس بإنشاء ملف مضيفين محلّي local واستخدامه بدلًا من الملف السابق، نستطيع فعل هذا عن طريق إنشاء ملف إعدادات Ansible جديد بداخل دليل العمل لدينا، والذي بإمكاننا استخدامه لإخبار Ansible بأن تبحث عن ملف المضيفين داخل نفس الدليل. نُنشِئ مُجلّدًا جديدًا (سنستخدمه لبقيّة هذا الدّرس): mkdir ~/ansible-php ننتقل إلى داخل المُجلّد الجديد: cd ~/ansible-php/نُنشِئ ملفًّا جديدًا يُدعى ansible.cfg ونفتحه من أجل تحريره باستخدام nano أو أي مُحرِّر نصوص تفضله: nano ansible.cfgنضيف خيار الإعدادات hostfile مع القيمة hosts في المجموعة [defaults] عن طريق نسخ ما يلي إلى الملف ansible.cfg: ansible.cfg [defaults] hostfile = hostsنحفظ الملف ansible.cfg ونغلقه، نقوم بعدها بإنشاء الملف hosts والذي يحتوي على عنوان IP لخادوم PHP حيث سيتم نشر تطبيقنا. nano hostsننسخ ما يلي لإضافة قسم من أجل php مع وضع عنوان IP الخاص بخادومك بدلًا من your_server_ip ووضع اسم المستخدم غير الجذري الذي قمت بإنشائه في المتطلبات الأساسيّة على خادوم PHP بدلًا من sammy: hosts [php] your_server_ip ansible_ssh_user=sammy نحفظ ونغلق الملف hosts، فلنقم بإجراء تحقّق أبسط للتأكد من قدرة Ansible على الاتصال بالمضيف كما هو متوقّع عن طريق استدعاء الوحدة ping على المجموعة php الجديدة: ansible php -m pingربّما تحصل على تحقّق من استيثاق مُضيف SSH اعتمادًا على كونك قد سجلّت الدخول إلى هذا المُضيف من قبل، ينبغي أن تعود ping باستجابة ناجحة تبدو كما يلي: Output 111.111.111.111 | success >> { "changed": false, "ping": "pong" تمّ الآن تثبيت وإعداد Ansible بنجاح، نستطيع الانتقال إلى إعداد خادوم الويب لدينا. الخطوة الثانية – تثبيت الحزم المطلوبةسنقوم في هذه الخطوة بتثبيت بعض حِزَم النظام المطلوبة باستخدام Ansible و apt، سنثبت تحديدًا git، nginx، sqlite3، mcrypt، وبعض حِزَم php5-*. نحتاج قبل إضافة الوحدة apt لتثبيت الحِزَم التي نريدها إلى إنشاء playbook بسيط (وهو عبارة عن قواعد تُحدِّد إعدادات Ansible)، سنبني على هذا الـ playbook مع تقدّمنا في هذا الدّرس، نقوم بإنشاء playbook جديد يُدعى php.yml: nano php.yml نلصق الإعدادات التالية، يُحدِّد أول سطرين مجموعة المضيفين التي نرغب باستخدامها (php) وتتحقّق من أنّها تنفّذ الأوامر باستخدام sudo افتراضيًّا، تُضيف باقي الأسطر وحدة بالحِزَم التي نحتاجها، تستطيع تخصيصها من أجل تطبيقاتك الخاصّة أو استخدام الإعدادات التالية إن كنت تتبع مثال تطبيق Laravel: --- - hosts: php sudo: yes tasks: - name: install packages apt: name={{ item }} update_cache=yes state=latest with_items: - git - mcrypt - nginx - php5-cli - php5-curl - php5-fpm - php5-intl - php5-json - php5-mcrypt - php5-sqlite - sqlite3نحفظ الملف php.yml، ونقوم أخيرًا بتشغيل ansible-playbook لتثبيت الحِزَم على الخادوم، يجب ألّا ننسى استخدام الخيار --ask-sudo-pass إن كان يتطلّب مستخدم sudo على خادوم PHP كلمة سر: ansible-playbook php.yml --ask-sudo-passالخطوة الثالثة – تعديل ملفات إعدادات النظامسنقوم في هذا القسم بتعديل بعض ملفّات إعدادات النظام على خادوم PHP، أهم خيار إعدادات يُمكِن تغييره (بغض النظر عن ملفّات Nginx، والتي سيتم تغطيتها في خطوة لاحقة) هو الخيار cgi.fix_pathinfo في php5-fpm، لأنّ القيمة الافتراضيّة له تُشكِّل خطرًا أمنيًّا. سنوضّح أوّلًا جميع الأقسام التي سنضيفها إلى هذا الملف، ونضمّن بعدها كامل الملف php.yml من أجلك لكي تقوم بنسخه ولصقه. يُمكِن استخدام الوحدة lineinfile للتأكّد من أنّ قيمة الإعدادات ضمن الملف مطابقة تمامًا لما نتوقعه، يُمكِن عمل هذا باستخدام تعبير نمطي regular expression عام بحيث تتمكّن Ansible من فهم معظم الصيغ التي من المحتمل أن يكون فيها المُعامِل، سنحتاج أيضًا لإعادة تشغيل php5-fpm وnginx لضمان تطبيق التغييرات، لذا نحتاج إلى إضافة مُداوِلَين handlers اثنين أيضًا في قسم جديد للمداولات handlers، تكون المداولات مثاليّة لهذا لأنّه يتم إطلاقها فقط عند تغيير المهمّة، ويتم أيضًا تشغيلها في نهاية الـ playbook، لذا يُمكن لمهام متعدّدة استدعاء نفس المُداوِل وسيعمل فقط مرّة واحدة. يبدو القسم الذي يُنفِّذ ما سبق كما يلي: name: ensure php5-fpm cgi.fix_pathinfo=0 lineinfile: dest=/etc/php5/fpm/php.ini regexp='^(.*)cgi.fix_pathinfo=' line=cgi.fix_pathinfo=0 notify: - restart php5-fpm - restart nginx handlers: - name: restart php5-fpm service: name=php5-fpm state=restarted - name: restart nginx service: name=nginx state=restartedملاحظة: خطأ برمجي bug في إصدار Ansible 1.9.1 يوجد خطا برمجي في إصدار Ansible 1.9.1 يمنع php5-fpm من إعادة تشغيلها مع الوحدة service، وقد استخدمنا هذا في مُداولاتنا. وحتى يتم إصدار إصلاح له نستطيع الالتفاف على هذه المشكلة عن طريق تغيير المُداوِل restart php5-fpm من استخدام الأمر service إلى استخدام الأمر shell كما يلي: - name: restart php5-fpm shell: service php5-fpm restartسيتجاوز هذا المشكلة ويعيد تشغيل php5-fpm بشكل صحيح. نحتاج بعد ذلك أيضًا إلى التأكّد من تمكين الوحدة php5-mcrypt، يُمكن فعل هذا عن طريق تنفيذ script يُدعى php5enmod باستخدام صدفة المهام shell task والتحقّق من وجود الملف 20-mcrypt.ini في مكانه عند تمكينه، لاحظ أنّنا نخبر Ansible أنّ المهمّة تقوم بإنشاء ملف مُحدَّد، فإن كان هذا الملف موجودًا فلن يتم تشغيل المهمّة: name: enable php5 mcrypt module shell: php5enmod mcrypt args: creates: /etc/php5/cli/conf.d/20-mcrypt.iniنفتح الآن الملف php.yml لتحريره مرّة أخرى: nano php.ymlنضيف المهام والمداولات السابقة بحيث يتطابق الملف مع التالي: --- - hosts: php sudo: yes tasks: - name: install packages apt: name={{ item }} update_cache=yes state=latest with_items: - git - mcrypt - nginx - php5-cli - php5-curl - php5-fpm - php5-intl - php5-json - php5-mcrypt - php5-sqlite - sqlite3 - name: ensure php5-fpm cgi.fix_pathinfo=0 lineinfile: dest=/etc/php5/fpm/php.ini regexp='^(.*)cgi.fix_pathinfo=' line=cgi.fix_pathinfo=0 notify: - restart php5-fpm - restart nginx - name: enable php5 mcrypt module shell: php5enmod mcrypt args: creates: /etc/php5/cli/conf.d/20-mcrypt.ini handlers: - name: restart php5-fpm service: name=php5-fpm state=restarted - name: restart nginx service: name=nginx state=restarted نقوم أخيرًا بتشغيل playbook: ansible-playbook php.yml --ask-sudo-pass يمتلك الآن الخادوم كافّة الحِزَم المطلوبة مُثبّتة عليه ومجموعة الإعدادات الأساسيّة جاهزة للانطلاق. الخاتمةتحدثنا في القسم الأول من هذا الدّرس عن طريقة تثبيت Ansible وإعداد البيئة بشكل عام من أجل التحضير لعمليّة نشر تطبيق PHP بسيط باستخدام Ansible، وسنكمل في القسم الثاني الحصول على Laravel وإعداده وإعداد خادوم Nginx لتخديم تطبيق PHP. ترجمة -وبتصرّف- لـ How To Deploy a Basic PHP Application Using Ansible on Ubuntu 14.04 لصاحبه Stephen Rees-Carter.
- 1 تعليق
-
- production
- نشر
-
(و 5 أكثر)
موسوم في:
-
تمّ تصميم أنظمة إدارة الإعدادات لتجعل التحكّم بعدد كبير من الخواديم أمرًا سهلًا لمديري الأنظمة وفرق العمليّات، فهي تسمح لنا بالتحكّم بالعديد من الأنظمة المختلفة بطريقة مؤتمتة من موقع مركزي واحد. وبينما تتوافر العديد من أنظمة إدارة الإعدادات الشائعة من أجل أنظمة Linux، مثل Chef وPuppet، فهي غالبًا معقدة أكثر من حاجة الناس، تُشكّل Ansible بديلًا رائعًا لهذه الخيارات لأنّها تحتوي على عقبات أقل بكثير عند البدء معها. سنناقش في هذا الدّرس كيفيّة تثبيت Ansible على خادوم Ubuntu وسنمر على بعض الأساسيات حول كيفيّة استخدام هذه البرمجيّة. كيف تعمل Ansible؟تعمل Ansible عن طريق إعداد أجهزة العملاء من خلال حاسوب يمتلك مكوّنات Ansible مثبّتة ومُعدّة عليه. تتواصل عبر قنوات SSH الاعتياديّة من أجل استعادة المعلومات من الأجهزة عن بُعد remote، إصدار الأوامر، ونسخ الملفّات، ولهذا السبب لا يتطلّب نظام Ansible تثبيت أي برمجيّات إضافيّة على حواسيب العملاء. هذه هي إحدى الطرق التي تُبسِّط فيها Ansible إدارة الخواديم، فيُمكِن إحضار أي خادوم يمتلك منفذ SSH مُعرَّض تحت مظلّة إعدادات Ansible بغض النظر عن الطور الذي يتواجد فيه ضمن دورة حياته. أي حاسوب نستطيع إدارته عبر SSH نستطيع أيضًا إدارته عبر Ansible. تتخذ Ansible نهج الوحدات modules ممّا يجعل من السهل تمديدها كي تستخدم وظائف من النظام الأساسي للتعامل مع حالات محدّدة، يُمكِن كتابة الوحدات باستخدام أيّة لغة وهي تتخاطب بواسطة JSON المعياريّة. إنّ ملفّات الإعدادات مكتوبة بشكل رئيسي بصيغة تسلسل البيانات YAML نظرًا لطبيعتها التعبيرية وتشابهها مع لغات الرقم markup الشائعة، تتمكن Ansible من التفاعل مع العملاء إمّا من خلال أداة سطر الأوامر أو عبر scripts للإعدادات تُدعى Playbooks. تثبيت Ansible على Ubuntuللبدء باستكشاف Ansible كوسيلة لإدارة خواديمنا المختلفة نحتاج إلى تثبيت برمجيّة Ansible على جهاز واحد على الأقل، سنستخدم خادوم Ubuntu من أجل هذا القسم. إنّ أفضل طريقة للحصول على Ansible في Ubuntu هي إضافة PPA المشروع (أرشيف الحِزَم الشخصية personal package archive) إلى نظامنا. للقيام بذلك على نحو فعال نحتاج لتثبيت الحزمة python-software-properties والتي ستعطينا القدرة على العمل مع PPA بسهولة: sudo apt-get update sudo apt-get install python-software-propertiesبعد أن يتم تثبيت الحزمة نستطيع إضافة Ansible PPA بكتابة الأمر التالي: sudo add-apt-repository ppa:rquillo/ansible نضغط ENTER لقبول إضافة الـ PPA. نحتاج بعدها لتحديث دليل حِزَم نظامنا بحيث يكون على دراية بالحِزَم المتوفرة في PPA، نستطيع بعدها تثبيت برمجيّة Ansible: sudo apt-get update sudo apt-get install ansible نمتلك الآن كافّة البرمجيّات المطلوبة لإدارة خواديمنا من خلال Ansible. إعداد مفاتيح SSHتتخاطب Ansible بالدرجة الأولى كما أشرنا سابقًا مع حواسيب العملاء عبر SSH، وعلى الرغم من أنّها تمتلك القدرة على التعامل مع استيثاق SSH authentication مُعتمِد على كلمة السر فتساعد مفاتيح SSH على إبقاء الأمور أبسط. بإمكاننا إعداد مفاتيح SSH بطريقتين مختلفتين اعتمادًا على إذا ما كنّا نمتلك مسبقًا المفتاح الذي نريد استخدامه. 1- إنشاء زوج مفاتيح SSH جديدإن لم تكن تمتلك مسبقًا زوج مفاتيح SSH ترغب في استخدامه من أجل إدارة Ansible فبإمكانك إنشاء واحد الآن على خادوم Ansible. سنقوم بإنشاء زوج مفاتيح SSH على خادوم Ansible من أجل استيثاقه مع المضيفين الذين يديرهم. نقوم بإنشاء زوج مفاتيح RSA key-pair بكتابة ما يلي عن طريق المستخدم الذي نتحكّم بـ Ansible من خلاله: ssh-keygen سيتم سؤالنا عن تحديد موقع الملف لزوج المفاتيح التي تم إنشاؤها، عبارة سر passphrase، وتأكيد عبارة السّر، نضغط Enter في جميع هذه المراحل لقبول القيم الافتراضيّة. ستكون المفاتيح الجديدة متاحة في دليل ~/.ssh الخاص بالمستخدم، يُدعى المفتاح العام (والذي يمكننا مشاركته) بـ id_rsa.pub، يُدعى المفتاح الخاص (والذي نبقيه بأمان) بـ id_rsa. نستطيع إضافتها إلى لوحة تحكّم DigitalOcean على سبيل المثال (إن كنت على Digital Ocean) للسماح لنا بتضمين مفتاح SSH الخاص بنا في الخواديم الجديدة التي أنشأناها، سيسمح هذا لخادوم Ansible بالدخول إلى الخواديم الجديدة عبر SSH فورًا بدون الحاجة لأي استيثاق آخر. لفعل هذا نضغط على الرابط “SSH Keys” الموجود في قائمة التصفح على اليسار، نضغط في الشاشة الجديدة على زر “Add SSH Key” الموجود في الزاوية العلوية اليمنى: ندخل الاسم الذي نريد ربطه مع هذا المفتاح في الحقل العلوي، ونكتب على خادوم Ansible ما يلي للحصول على محتويات مفتاحنا العام: cat ~/.ssh/id_rsa.pub ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDzmGgsqjSFuOBbjZB1sgquKpp3Ty+FgqoLrzjKbbk9VGOH6kM37aAhyxxmTQfe69lhYi/WCai+mrXOyY9IiQbUfZ4jsfPE9DS3zHhmnGiBWA7pedCTJ/Nhf06dmhAJIbExW3uDghbPbzbSA5Ihn1x0F5FXtSMDoFtyjcwUwJxc2z/kk9TKcFSl8qqf4IYBYE7c+EKaYRBjjDP4AQmiwjTPuipsmub7C0OGF0dTMatIa0lok6rwy91nmhCQV6polG0+Fsk4YrY8Yh5xz6wE0lOvc8BwP9nL0zsnw6Ey0MHV9BbMqtyD6x/fCurpIkMHJK4nv79rToSWA0AwoP/bJXh7 demo@ansible0 السلسلة النصية التي تعود لنا هي التي نحتاج لصقها في الحقل الثاني في لوحة تحكّم DigitalOcean: نضغط على “Create SSH Key” لإضافة مفتاحنا إلى لوحة التحكم، نستطيع الآن تضمين مفتاح SSH العام إلى الخواديم الجديدة التي نضيفها مما يسمح لنا بالتواصل مع خادوم Ansible، نحتاج فقط إلى اختيار المفتاح في القسم “Add optional SSH Keys” من عملية إنشاء خادوم جديد: 2- نقل زوج مفاتيح SSH موجود إلى Ansibleإن كنت تمتلك مسبقًا زوج مفاتيح SSH تريد استخدامه من أجل الاستيثاق مع خواديمك فبإمكانك نقل الإعتمادات credentials إلى خادوم Ansible الجديد بدلًا من إنشاء زوج جديد، يمتلك هذا ميّزة بأن يجعلها تعمل تلقائيًّا مع أي خواديم قمت بإعدادها مسبقًا لتستخدم هذا المفتاح. وعلى الحاسوب الآخر حيث قمنا بإعداد استيثاق مفتاح SSH من أجل الخواديم نحصل على المفتاح العام بكتابة ما يلي: cat ~/.ssh/id_rsa.pub ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDzmGgsqjSFuOBbjZB1sgquKpp3Ty+FgqoLrzjKbbk9VGOH6kM37aAhyxxmTQfe69lhYi/WCai+mrXOyY9IiQbUfZ4jsfPE9DS3zHhmnGiBWA7pedCTJ/Nhf06dmhAJIbExW3uDghbPbzbSA5Ihn1x0F5FXtSMDoFtyjcwUwJxc2z/kk9TKcFSl8qqf4IYBYE7c+EKaYRBjjDP4AQmiwjTPuipsmub7C0OGF0dTMatIa0lok6rwy91nmhCQV6polG0+Fsk4YrY8Yh5xz6wE0lOvc8BwP9nL0zsnw6Ey0MHV9BbMqtyD6x/fCurpIkMHJK4nv79rToSWA0AwoP/bJXh7 demo@ansible0نحتاج على خادوم Ansible إلى إنشاء دليل مخفي لتخزين المفاتيح، نقوم بتسميته .ssh كي يعلم برنامج SSH أين يجده: mkdir ~/.ssh نقوم بقفل النفاذ إلى هذا الدليل لكي نتمكن نحن فقط من دخوله أو الكتابة إليه: chmod 700 ~/.ssh ننتقل الآن إلى الدليل ونفتح ملفًّا يُدعى id_rsa.pub باستخدام محرّر النصوص: cd ~/.ssh nano id_rsa.pubنلصق خَرْج مفتاحنا العام من حاسوبنا الرئيسي إلى هذا الملف: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDzmGgsqjSFuOBbjZB1sgquKpp3Ty+FgqoLrzjKbbk9VGOH6kM37aAhyxxmTQfe69lhYi/WCai+mrXOyY9IiQbUfZ4jsfPE9DS3zHhmnGiBWA7pedCTJ/Nhf06dmhAJIbExW3uDghbPbzbSA5Ihn1x0F5FXtSMDoFtyjcwUwJxc2z/kk9TKcFSl8qqf4IYBYE7c+EKaYRBjjDP4AQmiwjTPuipsmub7C0OGF0dTMatIa0lok6rwy91nmhCQV6polG0+Fsk4YrY8Yh5xz6wE0lOvc8BwP9nL0zsnw6Ey0MHV9BbMqtyD6x/fCurpIkMHJK4nv79rToSWA0AwoP/bJXh7 demo@ansible0 نقوم بحفظ وإغلاق الملف، ونتحقّق من امتلاكه للأذونات الصحيحة بكتابة: chmod 644 id_rsa.pub الآن وبالعودة إلى حاسوبنا المحلّي المضبوط من أجل نفاذ مفاتيح SSH نكتب: cat ~/.ssh/id_rsa -----BEGIN RSA PRIVATE KEY----- MIIEpgIBAAKCAQEA85hoLKo0hbjgW42QdbIKriqad08vhYKqC684ym25PVRjh+pD N+2gIcl8Zk0H3uvZYWIv1gmsfpq1zsmPSIkG1H2eI7HzxPQ0qMx4ZpxogVgO6XnQ kyfzYX9OnZoQCSGxMVt7g4IWz2820gOSIZ9cdBeRV7UjA6Bbco3MFMCcXNs/5JPU ynBUpfKqn+CGAWBO3PhCmmEQY4wz+AEJosI0z7oqbJrm/AtDhhdHUzGrSGtJaJOq . . . . . . cqsqOEzXAoGBAPMJJ8RrKUBuSjVNkzebst9sBgNadmaoQUoMHUDr8KpCZhWAoHB7 1VKmq7VSphQSruI31qy2M88Uue1knC/nQr1bE1DITZgezETSsDqsAMBo8bqDN6TT qVJgG+TS9BRC+IowuzMVV5mzrfJjkrb+GG+xWSXrTLZMbeeTf+D0SfVo -----END RSA PRIVATE KEY----- سيكون الخَرْج طويلًا جدًّا. نعود الآن إلى خادوم Ansible، نحتاج إلى إنشاء ملف جديد في الدليل ~/.ssh: nano id_rsa نقوم بداخله بلصق نتائج الأمر السابق على حاسوبنا المحلّي: -----BEGIN RSA PRIVATE KEY----- MIIEpgIBAAKCAQEA85hoLKo0hbjgW42QdbIKriqad08vhYKqC684ym25PVRjh+pD N+2gIcl8Zk0H3uvZYWIv1gmsfpq1zsmPSIkG1H2eI7HzxPQ0qMx4ZpxogVgO6XnQ kyfzYX9OnZoQCSGxMVt7g4IWz2820gOSIZ9cdBeRV7UjA6Bbco3MFMCcXNs/5JPU ynBUpfKqn+CGAWBO3PhCmmEQY4wz+AEJosI0z7oqbJrm/AtDhhdHUzGrSGtJaJOq . . . . . . cqsqOEzXAoGBAPMJJ8RrKUBuSjVNkzebst9sBgNadmaoQUoMHUDr8KpCZhWAoHB7 1VKmq7VSphQSruI31qy2M88Uue1knC/nQr1bE1DITZgezETSsDqsAMBo8bqDN6TT qVJgG+TS9BRC+IowuzMVV5mzrfJjkrb+GG+xWSXrTLZMbeeTf+D0SfVo -----END RSA PRIVATE KEY----- نتأكّد من تضمين أسطر التحديد الموجودة في البداية والنهاية، فهي مطلوبة لكي يكون ملف المفتاح صالحًا، نحفظ الملف ونغلقه. نحتاج لتغيير الأذونات لإبقاء هذا الملف بأمان: chmod 600 id_rsa ستكون Ansible عند هذه النقطة قادرة على استخدام مفاتيح SSH هذه من أجل التواصل مع أي خادوم يمتلك المفتاح مُضمَّنًا عليه. إعداد مضيفي Ansibleتقوم Ansible بتتبّع جميع الخواديم التي يعلم عنها عن طريق ملف المضيفين “hosts”، نحتاج إلى إعداد هذا الملف أوّلًا قبل أن نتمكّن من بدء التواصل مع حواسيبنا الأخرى. نفتح الملف مع صلاحيّات جذريّة root كما يلي: sudo nano /etc/ansible/hosts سنرى ملفًّا يمتلك الكثير من أمثلة الإعدادات، وسيعمل أيّ منها لدينا فعليًّا، لذلك من أجل البدء نقوم بتعليق كافّة أسطر هذا الملف بإضافة “#” قبل كل سطر. سنبقي هذه الأمثلة في هذا الملف لتساعدنا في الإعداد إن أردنا تنفيذ حالات أكثر تعقيدًا في المستقبل. بعد أن يتم تعليق كافّة الأسطر نستطيع البدء بإضافة المضيفين الفعليين لدينا. يكون ملف المضيفين مرنًا إلى حدٍّ ما ويمكن إعداده بعدّة طرق مختلفة، تبدو الصياغة التي سنستخدمها كما يلي: [group_name] alias ansible_ssh_host=server_ip_address إنّ group_name هو وسم تنظيمي يسمح لنا بالإشارة لأي من الخواديم المدرجة بكلمة واحدة، الكنية هي مجرّد اسم للإشارة إلى ذلك الخادوم. لذا نتخيل في حالتنا أننا نمتلك ثلاثة خواديم نريد إعدادها مع Ansible، تكون هذه الخواديم قابلة للوصول من خلال خادوم Ansible بكتابة: ssh root@server_ip_address لن يتم سؤالنا عن كلمة سر إن أعددنا هذا بشكل صحيح، سنفترض أنّ عناوين IP لخواديمنا هي 192.0.2.1، 192.0.2.2، و192.0.2.3، سنقوم بإعداد هذا بحيث نستطيع الإشارة إليها بشكل مفرد كـ host1، host2، وhost3، أو كمجموعة باسم servers. هذه هي الكتلة التي ينبغي إضافتها إلى ملف المضيفين من أجل تحقيق هذا: [servers] host1 ansible_ssh_host=192.0.2.1 host2 ansible_ssh_host=192.0.2.2 host3 ansible_ssh_host=192.0.2.3 يمكن للمضيفين أن يكونوا ضمن مجموعات متعدّدة، وتستطيع المجموعات إعداد مُعامِلات parameters من أجل كل أعضائها، فلنجرّب هذا الآن. إن حاولنا مع إعداداتنا الحاليّة الاتصال بأي من المضيفين عن طريق Ansible فسيفشل الأمر (بافتراض أنّك لا تعمل عن طريق المستخدم الجذري root)، يحدث هذا لأنّه تم تضمين مفاتيح SSH من أجل المستخدم الجذري على الأنظمة البعيدة وستحاول Ansible الاتصال بشكل افتراضي بواسطة المستخدم الحالي، ستعطينا محاولة الاتصال هذا الخطأ: host1 | FAILED => SSH encountered an unknown error during the connection. We recommend you re-run the command using -vvvv, which will enable SSH debugging output to help diagnose the issue نستخدم على خادوم Ansible مستخدمًا يُدعى demo، ستحاول Ansible الاتصال إلى كل مضيف باستخدام ssh demo@server، لن يعمل هذا إن كان المستخدم demo غير موجود على النظام البعيد. نستطيع إنشاء ملف يُخبِر جميع الخواديم في المجموعة servers بالاتصال عن طريق المستخدم الجذري root. لفعل هذا نقوم بإنشاء دليل في بنية إعدادات Ansible يُدعى group_vars، ونستطيع ضمن هذا المجلّد إنشاء ملفّات مُنسّقة عن طريق YAML لكل مجموعة نريد إعدادها: sudo mkdir /etc/ansible/group_vars sudo nano /etc/ansible/group_vars/serversبإمكاننا وضع إعداداتنا هنا، تبدأ ملفّات YAML بـ “—” لذا تأكّد ألّا تنسى ذلك الجزء: --- ansible_ssh_user: rootنحفظ الملف ونغلقه عند الانتهاء. إن أردنا تحديد تفاصيل الإعدادات لكل خادوم بغض النظر عن مجموعته المرتبط بها فبإمكاننا وضع هذه التفاصيل في ملف في المسار /etc/ansible/group_vars/all، يمكن إعداد المضيفين بشكل مفرد بواسطة إنشاء ملفّات في دليل في المسار /etc/ansible/host_vars. استخدام أوامر Ansible بسيطةالآن بعد أن قمنا بإعداد المضيفين وضبطنا تفاصيل الإعدادات بشكلٍ كافٍ للسماح لنا بالاتصال بنجاح إلى مضيفينا، فبإمكاننا تجربة الأمر الأول لنا. نقوم بعمل ping لكل الخواديم التي أعددناها عن طريق كتابة: ansible -m ping allhost1 | success >> { "changed": false, "ping": "pong" } host3 | success >> { "changed": false, "ping": "pong" } host2 | success >> { "changed": false, "ping": "pong" } وهو اختبار بسيط للتأكّد من امتلاك Ansible لاتصال مع كافّة مضيفيه. تعني “all” كافّة المضيفين، وكان بإمكاننا بسهولة تحديد مجموعة كما يلي: ansible -m ping serversنستطيع أيضًا تحديد مضيف بشكل فردي: ansible -m ping host1بإمكاننا تحديد عدّة مضيفين بفصلهم بواسطة نقطتين: ansible -m ping host1:host2المقطع -m ping من الأمر هو تعليمة لـ Ansible كي تستخدم الوحدة “ping”، وهي بشكل مبسّط عبارة عن أوامر نستطيع تنفيذها على مضيفينا عن بُعد، تعمل الوحدة “ping” بعدّة طرق مثل أداة ping العاديّة في Linux، ولكن تقوم بدلًا من ذلك بالتحقّق من أجل اتصال Ansible. لا تأخذ الوحدة ping فعليًّا أيّة مُعطيات arguments، ولكن بإمكاننا تجربة أمر آخر لنرى كيفيّة عمل ذلك، نقوم بتمرير المعطيات إلى script بكتابة –a. تسمح لنا وحدة الصدفة “shell” بإرسال أمر طرفيّة terminal إلى المضيف البعيد واستعادة النتائج، على سبيل المثال لإيجاد استخدام الذاكرة على جهاز مضيفنا host1 نستطيع استخدام: ansible -m shell -a 'free -m' host1 host1 | success | rc=0 >> total used free shared buffers cached Mem: 3954 227 3726 0 14 93 -/+ buffers/cache: 119 3834 Swap: 0 0 0 الخاتمةينبغي أن تمتلك الآن خادوم Ansible مضبوطًا للتواصل مع الخواديم التي ترغب بالتحكم بها، تحقّقنا قدرة Ansible على التواصل مع كل مضيف واستخدمنا الأمر ansible لتنفيذ مهام بسيطة عن بُعد. وعلى الرغم من أنّ هذا مفيد لنا، لم نقم بتغطية أقوى ميّزة في Ansible في هذا الدّرس وهي الـ Playbooks، لقد قمنا بإعداد أساس رائع من أجل العمل مع خواديمنا من خلال Ansible، ولكن الجزء الأكبر سيتم الحديث عنه في درس لاحق عند تغطية كيفيّة استخدام الـ Playbooks لأتمتة الإعدادات لحواسيبنا عن بُعد. ترجمة -وبتصرّف- لـ How to Install and Configure Ansible on an Ubuntu 12.04 VPS لصاحبه Justin Ellingwood.
- 1 تعليق
-
- إدارة الإعدادات والنّشر
- ansible
- (و 6 أكثر)
-
هذا الدّرس هو جزء من سلسلة دروس حول نشر تطبيقات PHP باستخدام Ansible على Ubuntu، تحدّثنا في الأجزاء الأولى عن الخطوات الأساسيّة لنشر تطبيق، وفي بقيّة الأجزاء تكلمنا عن مواضيع أكثر تقدّمًا مثل قواعد البيانات، عفاريت الطابور queue daemons، وجدولة المهام (عبر cron). سنقوم في هذا الدّرس بالبناء على ما تعلمناه في الدروس السابقة عن طريق تحويل playbook في Ansible من دعمها لتطبيق واحد إلى دعمها لنشر تطبيقات PHP متعدّدة على خادوم أو عدّة خواديم. سنستخدم تطبيقات Lumen بسيطة كجزء أمثلتنا، ولكن يُمكِن تعديل هذه التعليمات بسهولة لتدعم أطر عمل وتطبيقات أخرى في حال كانت متواجدة لديك، من المفضّل أن تستخدم تطبيقات الأمثلة حتى تجد نفسك متآلفًا مع القيام بالتغييرات لِـ playbook. الخطوة الأولى – إضافة المزيد من التطبيقاتفي هذه الخطوة سنقوم بإعداد تطبيقين إضافيين في الـ playbook لدينا. الآن وقد أعدنا تصنيع الـ playbook سنستخدم متغيرات لتعريف التطبيقات، إنّ عملية إضافة تطبيقات جديدة لخادومنا هي عملية سهلة جدًّا، نقوم بإضافتها ببساطة إلى قائمة المتغيرات applications، وهنا تظهر قوة متغيرات Ansible. نفتح playbook من أجل تحريرها: nano php.yml نبحث في أعلى القسم vars عن الكتلة applications: Existing applications variable in php.yml applications: - name: laravel domain: laravel.example.com repository: https://github.com/do-community/do-ansible-adv-php.git branch: example نضيف تطبيقين اثنين: Updated applications variable in php.yml applications: - name: laravel domain: laravel.example.com repository: https://github.com/do-community/do-ansible-adv-php.git branch: example - name: one domain: one.example.com repository: https://github.com/do-community/do-ansible-php-example-one.git branch: master - name: two domain: two.example.com repository: https://github.com/do-community/do-ansible-php-example-two.git branch: master نحفظ الـ playbook ونقوم بتشغيلها: ansible-playbook php.yml --ask-sudo-pass قد تستغرق هذه الخطوة بعض الوقت بينما يقوم الـ composer بإعداد التطبيقات الجديدة، وعندما ينتهي سنلاحظ تغيير عدد من المهام، وإن دققنا أكثر سنلاحظ أنّه سيتم عرض كل عنصر ناتج عن الحلقة، يخبرنا الأول وهو تطبيقنا الأصل بعبارة ok أو skipped، بينما يخبرنا التطبيقان الجديدان بالحالة changed. والأهم من ذلك أنّه إذا زرنا النطاقات الثلاثة لمواقعنا التي أعددناها في متصفح الإنترنت فينبغي أن نلاحظ ثلاثة مواقع مختلفة. الأول يبدو مألوفًا لنا، أما الموقعان الآخران سيعرضان: http://one.example.com/ This is example app one! http://two.example.com/ This is example app two! وبذلك قمنا بنشر تطبيقي ويب جديدين عن طريق تحديث قائمة التطبيقات ببساطة. الخطوة الثانية – استخدام متغيرات المضيفين Host Variablesسنستخرج في هذه الخطوة متغيراتنا إلى متغيرات المضيفين. بالرجوع إلى الوراء نجد أنّ متغيرات الـ playbook جيدة، ولكن ماذا لو أردنا نشر تطبيقات مختلفة على خواديم مختلفة باستخدام نفس الـ playbook؟ نستطيع عمل تحقّق شرطي على كل مهمّة لإيجاد الخادوم الذي يقوم بتشغيل المهمة، أو نستطيع استخدام متغيرات المضيفين، وهي تمامًا كما تبدو عليه: متغيرات تُطبَّق على مضيف معيّن بدلًا من كافّة المضيفين عبر الـ playbook. يمكن تعريف متغيرات المضيف سطريًّا inline بداخل الملف hosts كما فعلنا مع المتغير ansible_ssh_user أو يمكن تعريفها في ملف مخصّص لكل مضيف داخل الدليل host_vars. في البداية نقوم بإنشاء دليل جديد إلى جانب الملف hosts والـ playbook، نقوم بتسمية الدليل بـ host_vars: mkdir host_vars نحتاج بعدها إلى إنشاء ملف من أجل المضيف، الاتفاقية التي تستخدمها Ansible هي من أجل أن يتوافق اسم الملف مع اسم المضيف في الملف hosts، لذلك على سبيل المثال إن كان يبدو الملف hosts لدينا كما يلي: Ansible hosts file your_first_server_ip ansible_ssh_user=sammy فينبغي أن نقوم بإنشاء ملف يُدعى host_vars/your_first_server_ip، فلنقم بإنشائه الآن: nano host_vars/your_first_server_ip تستخدم ملفّات المضيفين YAML من أجل تنسيقها تمامًا كما هو الحال مع الـ playbooks، ويعني هذا أنّنا نستطيع نسخ القائمة applications إلى ملف المضيفين الجديد لدينا بحيث يبدو كما يلي: New host_vars/your_first_server_ip file --- applications: - name: laravel domain: laravel.example.com repository: https://github.com/do-community/do-ansible-adv-php.git branch: example - name: one domain: one.example.com repository: https://github.com/do-community/do-ansible-php-example-one.git branch: master - name: two domain: two.example.com repository: https://github.com/do-community/do-ansible-php-example-two.git branch: master نقوم بحفظ ملف المضيفين الجديد ونفتح الـ playbook لتحريرها: nano php.yml نحدّث أعلى الملف لإزالة كامل القسم applications: Updated top of php.yml --- - hosts: php sudo: yes vars: wwwuser: www-data tasks: . . . نحفظ الـ playbook ونقوم بتشغيلها: ansible-playbook php.yml --ask-sudo-pass وعلى الرغم من أنّنا نقلنا متغيراتنا من الـ playbook إلى ملف المضيفين فيجب أن يبقى الخرج نفسه ولا يجب أن يتم تبليغنا عن تغييرات من قبل Ansible، وكما نرى يعمل host_vars بنفس الطريقة التي يعمل بها vars في الـ playbook، ولكنّه مُخصّص للمضيف. ستكون المتغيرات المُعرّفة في ملفّات host_vars قابلة للوصول عبر كامل الـ playbooks التي تدير الخادوم، وهو مفيد من أجل الخيارات والإعدادات الشائعة، ومع ذلك كن حذرًا من استخدام اسم شائع قد يعني أشياء مختلفة عبر الـ playbooks المختلفة. الخطوة الثالثة – نشر التطبيقات على خادوم آخرسنستخدم في هذه الخطوة ملفات المضيفين الجديدة وننشر تطبيقاتنا على خادوم آخر. نحتاج في البداية إلى تحديث ملف المضيفين hosts بمضيفنا الجديد، نفتحه من أجل تحريره: nano hosts ونقوم بإضافة المضيف الجديد: Ansible hosts file your_first_server_ip ansible_ssh_user=sammy your_second_server_ip ansible_ssh_user=sammy نحفظ الملف ونغلقه. نحتاج بعدها إلى إنشاء ملف مضيفين جديد، كما فعلنا مع أول ملف: nano host_vars/your_second_server_ip تستطيع انتقاء واحد أو أكثر من تطبيقات مثالنا وإضافتها إلى ملف المضيف لديك، فإذا أردت مثلًا نشر مثالنا الأصلي والمثال الثاني إلى خادوم جديد فيجب أن تستخدم: New host_vars/your_second_server_ip file --- applications: - name: laravel domain: laravel.example2.com repository: https://github.com/do-community/do-ansible-adv-php.git branch: example - name: two domain: two.example2.com repository: https://github.com/do-community/do-ansible-php-example-two.git branch: master نقوم بحفظ playbook. وأخيرًا نقوم بتشغيلها: ansible-playbook php.yml --ask-sudo-pass ستستغرق Ansible وقتًا ليتم تشغيلها لأنّها تقوم بإعداد كل شيء على خادومنا الثاني، وعندما تنتهي نفتح تطبيقاتنا التي اخترناها في المتصفح (استخدمنا في هذا المثال laravel.example2.com وtwo.example2.com) وللتأكد من أنّه تم إعدادها بشكل صحيح يجب أن نرى التطبيقات المحدّدة التي اخترناها من أجل ملف المضيفين، وينبغي ألّا تحدث أيّة تغييرات على خادومنا الأصلي. الخاتمةأخذنا في هذا الدرس playbook تطبيق وحيد تعمل بشكل كامل وقمنا بتحويلها لتدعم تطبيقات متعددة عبر عدّة خواديم، وبجمعها مع المواضيع التي تمت تغطيتها في الدروس السابقة يجب أن تمتلك كل ما تحتاجه لكتابة playbook كاملة لنشر تطبيقاتك، وكما هو الحال مع الدروس السابقة فلا زلنا لم نسجل الدخول بشكل مباشر باستخدام SSH. ومن المؤكد أنك لاحظت مدى بساطة إضافة المزيد من التطبيقات والمزيد من الخواديم بعد الانتهاء من تجهيز بنية الـ playbook، وهنا تكمن قوة Ansible وهو ما يجعلها مرنة جدًّا وسهلة الاستخدام. ترجمة -وبتصرّف- لـ How To Deploy Multiple PHP Applications using Ansible on Ubuntu 14.04 لصاحبه Stephen Rees-Carter.
-
- playbook
- production
-
(و 5 أكثر)
موسوم في:
-
سنواصل في هذا الدّرس حديثنا حول نشر تطبيق PHP باستخدام Ansible. هذا الدّرس هو الجزء الثّاني للسلسلة، إذا لم تقرأ الجزء الأول فمن الأفضل أن تشرع به أوّلا، حيث نُعالج فيه تثبيت Ansible وإعداده. إذا لم تكن لديك أيّة خلفية مُسبقة حول Ansible فمن الأفضل أن تبدأ مع مقال كيفيّة تثبيت وإعداد Ansible على Ubuntu. سنتحدث في هذا القسم من الدّرس عن كيفية الحصول على إطار عمل Laravel وإعداده وإعداد خادوم Nginx لتخديم تطبيق PHP. سنستخدم إطار عمل Laravel كمثال عن تطبيق PHP ولكن يُمكِن تعديل هذه التعليمات بسهولة لتدعم أطر عمل وتطبيقات أخرى في حال كانت متواجدة لديك. المتطلبات الأساسيةيبدأ هذا الدّرس مباشرة من حيث انتهى الجزء الأول من هذه السلسلة، ونحتاج كافّة الملفّات والإعدادات التي تم الحصول عليها في ذلك الجزء، إن لم تقم بإكمال أول درس من هذه السلسلة فنرجو أن تفعل ذلك قبل متابعة هذا الدّرس. الخطوة الأولى – استنساخ مستودع Gitفي هذا القسم سنقوم باستنساخ clone مستودع إطار عمل Laravel إلى الخادوم الخاص بنا باستخدام Git، سنشرح مثل الخطوة الثالثة كافّة الأقسام التي سنقوم بإضافتها إلى الـ playbook، ونضمّن بعدها كامل ملف php.yml من أجلك لتقوم بنسخه ولصقه. وقبل أن نستنسخ مستودع Git الخاص بنا نحتاج إلى التأكّد من وجود الدليل var/www/، نستطيع فعل هذا عن طريق إنشاء مهمّة مع وحدة الملف: - name: create /var/www/ directory file: dest=/var/www/ state=directory owner=www-data group=www-data mode=0700 نحتاج كما أشرنا سابقًا إلى استخدام الوحدة Git لاستنساخ المستودع إلى الخادوم الخاص بنا، وهي عمليّة بسيطة لأنّ كل ما نحتاجه بشكل طبيعي من أجل الأمر git clone هو مستودع المصدر source repository، في هذه الحالة سنعرّف أيضًا الوجهة destination ونخبر Ansible بعدم تحديث المستودع في حال وجوده مسبقًا عن طريق تعيين update=no، وبما أنّنا نستخدم Laravel سنستعمل رابط مستودع git التالي: https://github.com/laravel/laravel.git نحتاج مع ذلك إلى تشغيل المهمّة عن طريق المستخدم www-data للتأكّد من أنّ الصلاحيّات صحيحة، ولعمل هذا نستطيع إخبار Ansible أن ينفّذ الأمر كمستخدم محدّد باستخدام sudo، ستبدو المهمّة النهائية كما يلي: - name: Clone git repository git: > dest=/var/www/laravel repo=https://github.com/laravel/laravel.git update=no sudo: yes sudo_user: www-data ملاحظة: من أجل المستودعات المعتمدة على SSH نستطيع إضافة accept_hostkey=yes لمنع التحقّق من المضيف على SSH من تعليق المهمّة. نفتح الملف php.yml لتحريره: nano php.yml نضيف المهام السابقة إلى الـ playbook، يجب أن يبدو الملف النهائي كما يلي: ... - name: enable php5 mcrypt module shell: php5enmod mcrypt args: creates: /etc/php5/cli/conf.d/20-mcrypt.ini - name: create /var/www/ directory file: dest=/var/www/ state=directory owner=www-data group=www-data mode=0700 - name: Clone git repository git: > dest=/var/www/laravel repo=https://github.com/laravel/laravel.git update=no sudo: yes sudo_user: www-data handlers: - name: restart php5-fpm service: name=php5-fpm state=restarted - name: restart nginx service: name=nginx state=restarted نحفظ الـ playbook ونغلقها، ثمّ نقوم بتشغيلها: ansible-playbook php.yml --ask-sudo-pass الخطوة الثانية – إنشاء تطبيق باستخدام Composerسنستخدم في هذه الخطوة Composer لتثبيت تطبيق PHP واعتمادياته dependencies. يمتلك Composer الأمر create-project الذي يقوم بتثبيت كافّة الاعتماديات المطلوبة ومن ثمّ يُشغِّل خطوات إنشاء المشروع المُعرَّفة في القسم post-create-project-cmd من الملف composer.json، وهي الطريق المفضّلة للتأكّد من إعداد التطبيق بشكل صحيح لاستخدامه لأول مرّة. نستطيع استخدام مهمّة Ansible التالية لتنزيل وتثبيت Composer بشكل عمومي كـ usr/local/bin/composer/، سيكون بعدها قابلًا للنفاذ من قبل أي شخص يستخدم الخادوم بما فيهم Ansible: - name: install composer shell: curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer args: creates: /usr/local/bin/composer ومع وجود Composer مُثبّتًا لدينا فهنالك وحدة لـ Composer يُمكننا استخدامها، في حالتنا نريد إخبار Composer عن مكان مشروعنا (باستخدام المُعامِل working_dir)، ونريد أيضًا تنفيذ الأمر create-project، نحتاج أيضًا لإضافة المُعامِل optimize_autoloader=no لأنّ هذا العَلَم غير مدعوم من قبل الأمر create-project، وكما في حالة الأمر git يجب علينا تنفيذ هذا عن طريق المستخدم www-data للتأكّد من صلاحيّة الأذونات permissions، وبوضع كل ذلك معًا نحصل على هذه المهمّة: - name: composer create-project composer: command=create-project working_dir=/var/www/laravel optimize_autoloader=no sudo: yes sudo_user: www-data ملاحظة: قد تستغرق المهمّة create-project قدرًا كبيرًا من الوقت على خادوم جديد، حيث يمتلك الـ Composer ذاكرة تخزين مؤقّت فارغة ويحتاج إلى تنزيل كل شيء من جديد. نفتح الآن الملف php.yml لتحريره: nano php.yml نضيف المهام السابقة في نهاية القسم tasks فوق handlers بحيث تتوافق نهاية الـ playbook مع التالي: ... - name: Clone git repository git: > dest=/var/www/laravel repo=https://github.com/laravel/laravel.git update=no sudo: yes sudo_user: www-data - name: install composer shell: curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer args: creates: /usr/local/bin/composer - name: composer create-project composer: command=create-project working_dir=/var/www/laravel optimize_autoloader=no sudo: yes sudo_user: www-data handlers: - name: restart php5-fpm service: name=php5-fpm state=restarted - name: restart nginx service: name=nginx state=restarted نقوم أخيرًا بتشغيل الـ playbook: ansible-playbook php.yml --ask-sudo-pass ما الذي سيحدث إن قمنا بتشغيل Ansible مرّة أخرى الآن؟ سيتم تشغيل composer create-project مرّة أخرى، وفي حالة Laravel يعني هذا APP_KEY جديد، لذا نريد بدلًا من ذلك تعيين المهمّة لتعمل فقط بعد استنساخ clone جديد، نستطيع ضمان أنّها تعمل فقط مرّة واحدة عن طريق تسجيل متغيّر يحتوي نتائج المهمّة git clone ومن ثمّ التحقّق من هذه النتائج داخل المهمّة composer create-project، إن تمّ تغيير المهمّة git clone فسيتم تنفيذ composer create-project، أمّا إن لم يحدث ذلك فسيتم تخطّيها. ملاحظة: يبدو أنّه يوجد خطأ برمجي في بعض إصدارات وحدة composer في Ansible، وربّما تعيد الخَرْج OK بدلًا من Changed، حيث تتجاهل أنّه تمّ تنفيذ scripts على الرغم من أنّه لم يتم تثبيت اعتماديات. نفتح الملف php.yml من أجل تحريره: nano php.yml نبحث عن المهمّة git clone، نضيف الخيار register لحفظ نتائج المهمّة إلى المتغير cloned كما يلي: - name: Clone git repository git: > dest=/var/www/laravel repo=https://github.com/laravel/laravel.git update=no sudo: yes sudo_user: www-data register: cloned </code>نبحث بعدها عن المهمّة composer create-project، نضيف الخيار when للتحقّق من المتغيّر cloned لنرى إن تغيّرت قيمته أم لا: - name: composer create-project composer: command=create-project working_dir=/var/www/laravel optimize_autoloader=no sudo: yes sudo_user: www-data when: cloned|changed نقوم بحفظ الـ playbook وتشغيلها: ansible-playbook php.yml --ask-sudo-pass سيوقف الـ Composer الآن تغيير APP_KEY في كل مرّة يتم تشغيله فيها. الخطوة الثالثة – تحديث متغيرات البيئةفي هذه الخطوة سنقوم بتحديث متغيّرات البيئة Environment Variables من أجل تطبيقنا. يأتي Laravel مع ملف env. بشكل افتراضي والذي يقوم بتعيين قيمة APP_ENV إلى local وقيمة APP_DEBUG إلى true، نحتاج إلى تبديل هذه القيم إلى production و false على الترتيب، يُمكِن فعل هذا ببساطة باستخدام الوحدة lineinfile مع المهام التالية: - name: set APP_DEBUG=false lineinfile: dest=/var/www/laravel/.env regexp='^APP_DEBUG=' line=APP_DEBUG=false - name: set APP_ENV=production lineinfile: dest=/var/www/laravel/.env regexp='^APP_ENV=' line=APP_ENV=production نفتح الملف php.yml لتحريره: nano php.yml نضيف هذه المهمّة إلى الـ playbook، يجب أن تبدو نهاية الملف متطابقة مع التالي: ... - name: composer create-project composer: command=create-project working_dir=/var/www/laravel optimize_autoloader=no sudo: yes sudo_user: www-data when: cloned|changed - name: set APP_DEBUG=false lineinfile: dest=/var/www/laravel/.env regexp='^APP_DEBUG=' line=APP_DEBUG=false - name: set APP_ENV=production lineinfile: dest=/var/www/laravel/.env regexp='^APP_ENV=' line=APP_ENV=production handlers: - name: restart php5-fpm service: name=php5-fpm state=restarted - name: restart nginx service: name=nginx state=restarted نقوم بحفظ الـ playbook وتشغيلها: ansible-playbook php.yml --ask-sudo-pass إنّ الوحدة lineinfile مفيدة جدًا من أجل التطويعات tweaks السريعة لأي ملف نصّي، وهي رائعة للتأكّد من تعيين متغيّرات بيئة كهذه بشكل صحيح. الخطوة الرابعة – إعداد Nginxسنقوم في هذا القسم بإعداد Nginx لتخديم تطبيق PHP. إن زرت الآن الخادوم الخاص بك في متصفّح الإنترنت (على سبيل المثال http://your_server_ip )، فسترى صفحة Nginx الافتراضيّة بدلاً من صفحة المشروع الجديد في Laravel، حدث هذا لأنّنا لا زلنا نحتاج إلى إعداد خادوم ويب Nginx لدينا لتخديم التطبيق من الدليل var/www/laravel/public/، لفعل هذا نحتاج لتحديث إعدادات Nginx الافتراضيّة بهذا الدليل وإضافة دعم من أجل php-fpm بحيث يستطيع التعامل مع PHP scripts. نقوم بإنشاء ملف جديد يُدعى nginx.conf: nano nginx.conf نحفظ كتلة الخادوم التالية بداخل هذا الملف، تستطيع متابعة الخطوة الرابعة من هذا الدّرس من أجل المزيد من التفاصيل حول إعدادات Nginx، تُحدِّد التعديلات التالية مكان دليل Laravel العام وتتحقّق من استخدام Nginx لاسم المضيف الذي عرّفناه في الملف hosts كـ server_name مع المتغيّر inventory_hostname. nginx.conf server { listen 80 default_server; listen [::]:80 default_server ipv6only=on; root /var/www/laravel/public; index index.php index.html index.htm; server_name {{ inventory_hostname }}; location / { try_files $uri $uri/ =404; } error_page 404 /404.html; error_page 500 502 503 504 /50x.html; location = /50x.html { root /var/www/laravel/public; } location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } } نحفظ الملف nginx.conf ونغلقه. بإمكاننا الآن استخدام وحدة القالب template module لدفع ملف الإعدادات الجديدة عبرها، تبدو وحدة template مشابهة جدًا للوحدة copy، ولكن يوجد فرق كبير بينهما، فالوحدة copy ستنسخ ملف أو عدّة ملفّات بدون القيام بأيّة تغييرات، بينما تنسخ الوحدة template ملفًّا واحدًا وتقوم بتحليل كافّة الملفّات الموجودة بداخله، ولأنّنا استخدمنا {{ inventory_hostname }} داخل ملف إعداداتنا سنستخدم الوحدة template بحيث يتم تحليلها بداخل عنوان IP الذي استخدمناه في الملف hosts، وبهذه الطريقة لا يتوجّب علينا كتابة شيفرة محدّدة لملفّات الإعدادات التي تستخدمها Ansible. ومع ذلك فكما هو معتاد عند كتابة المهام نحتاج إلى أن نأخذ بعين الاعتبار ما سيحدث على الخادوم، ولأنّنا نقوم بتغيير إعدادات Nginx نحتاج لإعادة تشغيل Nginx و php-fpm، يتم هذا باستخدام الخيار notify: - name: Configure nginx template: src=nginx.conf dest=/etc/nginx/sites-available/default notify: - restart php5-fpm - restart nginx نفتح ملف php.yml: nano php.yml نضيف مهمّة nginx هذه في نهاية قسم المهام، ينبغي أن يبدو الملف php.yml كما يلي: php.yml --- - hosts: php sudo: yes tasks: - name: install packages apt: name={{ item }} update_cache=yes state=latest with_items: - git - mcrypt - nginx - php5-cli - php5-curl - php5-fpm - php5-intl - php5-json - php5-mcrypt - php5-sqlite - sqlite3 - name: ensure php5-fpm cgi.fix_pathinfo=0 lineinfile: dest=/etc/php5/fpm/php.ini regexp='^(.*)cgi.fix_pathinfo=' line=cgi.fix_pathinfo=0 notify: - restart php5-fpm - restart nginx - name: enable php5 mcrypt module shell: php5enmod mcrypt args: creates: /etc/php5/cli/conf.d/20-mcrypt.ini - name: create /var/www/ directory file: dest=/var/www/ state=directory owner=www-data group=www-data mode=0700 - name: Clone git repository git: > dest=/var/www/laravel repo=https://github.com/laravel/laravel.git update=no sudo: yes sudo_user: www-data register: cloned - name: install composer shell: curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer args: creates: /usr/local/bin/composer - name: composer create-project composer: command=create-project working_dir=/var/www/laravel optimize_autoloader=no sudo: yes sudo_user: www-data when: cloned|changed - name: set APP_DEBUG=false lineinfile: dest=/var/www/laravel/.env regexp='^APP_DEBUG=' line=APP_DEBUG=false - name: set APP_ENV=production lineinfile: dest=/var/www/laravel/.env regexp='^APP_ENV=' line=APP_ENV=production - name: Configure nginx template: src=nginx.conf dest=/etc/nginx/sites-available/default notify: - restart php5-fpm - restart nginx handlers: - name: restart php5-fpm service: name=php5-fpm state=restarted - name: restart nginx service: name=nginx state=restarted نقوم بحفظ الـ playbook وتشغيلها مرّة أخرى: ansible-playbook php.yml --ask-sudo-pass حالما تكتمل نعود إلى متصفحنا ونقوم بتحديثه، ينبغي أن نرى الآن صفحة المشروع الجديد في Laravel. الخاتمةيُغطّي هذا الدرس نشر تطبيق PHP مع مستودع عام، وبينما يكون هذا مثاليًّا من أجل تعلّم كيفيّة عمل Ansible، فإنّك لن تعمل دائمًا على مشاريع مفتوحة المصدر بشكل كامل مع مستودعات مفتوحة، ويعني هذا أنّك ستحتاج إلى استيثاق git clone في الخطوة الثالثة مع مستودعك الخاص، يُمكِن فعل هذا بسهولة باستخدام مفاتيح SSH. على سبيل المثال بعدما تقوم بإنشاء وإعداد مفاتيح نشر SSH على مستودعك تستطيع استخدام Ansible لنسخها وإعدادها على خادومك قبل مهمّة git clone: - name: create /var/www/.<abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr>/ directory file: dest=/var/www/.<abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr>/ state=directory owner=www-data group=www-data mode=0700 - name: copy private <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr> key copy: src=deploykey_rsa dest=/var/www/.<abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr>/id_rsa owner=www-data group=www-data mode=0600يجب أن يسمح هذا للخادوم بالاستيثاق بشكل صحيح ونشر تطبيقك. لقد قمنا للتو بنشر تطبيق PHP بسيط على خادوم ويب Nginx معتمد على Ubuntu باستخدام Composer لإدارة الاعتماديّات، وتمّ كل هذا بدون الحاجة للدخول مباشرة إلى الخادوم الخاصّ بنا وتنفيذ أي أمر بشكل يدوي. ترجمة -وبتصرّف- لـ How To Deploy a Basic PHP Application Using Ansible on Ubuntu 14.04 لصاحبه Stephen Rees-Carter.
-
هذا الدّرس هو الجزء الثّاني من سلسلة من 6 دروس حول "نظرة عامة على إنشاء تطبيقات موجهة لبيئة الإنتاج". إذا لم تقرأ الدّرس الأول فألق نظرة عليه قبل أن تواصل القراءة. سنعدّ في هذا الجزء من السّلسلة تطبيق PHP الذي اخترناه مثالا (ووردبريس) إضافة إلى خادوم أسماء نطاقات DNS خاص. سيستعمل مستخدمو التطبيق اسمَ النطاق للوصول إليه؛ عبر العنوان https://www.example.com على سبيل المثال. يحيل العنوان إلى موزع الحِمل الذي سيعمل وسيطا عكسيا Reverse proxy لخواديم التطبيق التي تتصل بدورها بخادوم قاعدة البيانات. يمكِّننا استخدامُ نظام أسماء نطاقات خاصة Private DNS من الإشارة إلى عناوين الخواديم ضمن الشبكة الداخلية بأسماء المستضيفات الخاصة بها مما يسهل من عملية إعداد الخواديم. سنعد العناصر للتوّ التي أشرنا إليها على ستة خواديم، طبقا للترتيب التالي: نظام أسماء نطاقات خاصة (المستضيفان ns1 وns2).خادوم قاعدة البيانات (db1).خواديم التطبيق (app1 وapp2).موزع حمل (lb1). فلنبدأ بإعداد النطاقات. خواديم النطاقات الداخليةيساعد استخدام أسماء نطاقات بدلا من عناوين IP في التعرف على الخواديم التي نعمل عليها، كما أنه ضروري حال إدارة الكثير من الخواديم؛ إذ يمكّن من إحلال خادوم مكان آخر بمجرد تحديث سجلات النطاق (ضمن ملف وحيد) بدلا من من تحديث عناوين IP ضمن الكثير من ملفات الإعداد. سنعدّ نظام نطاقات للإحالة إلى عناوين الشبكة الداخلية التي توجد بها الخواديم بدلا من عناوين IP. سنشير إلى كل عنوان في الشبكة الداخلية بمستضيف ضمن النطاق الفرعي nyc3.example.com. سيكون عنوان خادوم قاعدة البيانات ضمن الشبكة الداخلية - على سبيل المثال - db1.nyc3.example.com؛ وهو ما ستترجمه خواديم النطاقات إلى عنوان IP داخلي (خاص). تنبغي الإشارة إلى أن اختيار اسم النطاق الفرعي nyc3.example.com اعتباطي. في العادة يُستخدم اسم الموقع الجغرافي للنطاق الفرعي؛ في مثالنا، تشير nyc3 إلى أن الخواديم تتواجد في مركز البيانات NYC3، وexample.com إلى اسم النطاق الخاص بالتطبيق. ستحصل على خادومي BIND هما ns1 وns2. أضف عناوين IP الخاصة بجميع الخواديم التي تخطط لإعدادها إن كنت تعرفها سلفًا، وإلا أضف سجلات النطاق بالتزامن مع إنشاء الخواديم. ننتقل لإعداد خادوم قاعدة البيانات. إعداد خادوم قاعدة البياناتنريد - طبقا للخطة - توزيع الحمل بين خواديم التطبيقات؛ أي تلك التي تشغِّل PHP وApache، لذا سنفْصِل قاعدة البيانات عن خواديم التطبيق لجعلها على خادوم خاص بها. من المهم جدا فصل قاعدة البيانات عن التطبيق في حال أردنا إمكانية التوسع أفقيا Horizontally Scaling (إضافة خواديم جديدة لتعمل مع تلك الموجودة) في تطبيقات PHP. تغطي هذه الفقرة كل الخطوات الضرورية لإعداد خادوم قاعدة البيانات، لكن يمكنك معرفة المزيد عن إعداد قاعدة بيانات MySQL بعيدة بقراءة مقال كيفية إعداد قاعدة بيانات بعيدة لتحسين أداء موقع يستخدِم MySQL. تثبيت MySQLنفذ الأمرين التاليين على خادوم قاعدة البيانات (db1) لتثبيت خادوم MySQL: sudo apt-get update sudo apt-get -y install mysql-serverأدخل كلمة السر التي تريد استخدامها للحساب الإداري في MySQL عندما يُطلب منك ذلك. نفذ: sudo mysql_install_db sudo mysql_secure_installationستحتاج لإدخال كلمة سر المستخدِم الإداري التي اخترتها عند تثبيت خادوم MySQL؛ بعدها سيسألك إن كنت تريد تغيير كلمة السر هذه، اضغط زر N إذا كنت لا تريد تغييرها. بالنسبة لبقية الأسئلة اضغط زر Enter لتأكيد الاختيارات الافتراضية. إعداد MySQL لاستخدام واجهة الشبكة الداخليةافتح ملف إعداد MySQL عبر الأمر التالي: sudo nano /etc/mysql/my.cnfابحث عن bind-address وحدد قيمة المتغير بعنوان IP قاعدة البيانات ضمن الشبكة الداخلية: bind-address = db1.nyc3.example.comاحفظ الملف ثم أغلقه. أعد تشغيل MySQL: sudo service mysql restartضبط قاعدة البيانات ومستخدميهانحتاج الآن لإنشاء قاعدة بيانات والمستخدمين الذين ستتصل خواديم التطبيقات عن طريقهم إلى قاعدة البيانات. استخدم الأمر التالي للدخول إلى سطر أوامر MySQL: mysql -u root -pأدخل كلمة السر عندما تُطلب. أنشئ قاعدة بيانات بتنفيذ الأمر التالي في سطر أوامر MySQL: CREATE DATABASE app;يرفق خادوم MySQL كل مستخدم بالخواديم التي يمكنه منها الاتصال بقاعدة بيانات. يوجد في مثالنا خادوما تطبيق يتصلان بقاعدة البيانات؛ لذا سننشئ مستخدما لكل واحد منهما. أنشئ مستخدما في قاعدة البيانات باسم appuser يمكنه الاتصال من العناوين الداخلية لخواديم التطبيقات (أي app1 وapp2). يجب استخدام نفس كلمة السر للمستخدمَيْن (اختر كلمة سر واكتبها مكان password في الأمرين أدناه): CREATE USER 'appuser'@'app1.nyc3.example.com' IDENTIFIED BY 'password'; CREATE USER 'appuser'@'app2.nyc3.example.com' IDENTIFIED BY 'password';سنضبط في ما بعد امتيازات المستخدم appuser، نكتفي الآن بإعطائه تحكما كاملا على قاعدة البيانات app: GRANT ALL PRIVILEGES ON app.* TO 'appuser'@'app1.nyc3.example.com'; GRANT ALL PRIVILEGES ON app.* TO 'appuser'@'app2.nyc3.example.com'; FLUSH PRIVILEGES;تضمن الامتيازات الممتدة أن سكربت تثبيت التطبيق سيتمكن من تثبيته على قاعدة البيانات. إن كان لديك أكثر من خادومي تطبيقات، فيجب أن تنشئ حسابات المستخدمين الآن بنفس الكيفية. للخروج من سطر أوامر MySQL: exitاكتمل الآن إعداد خادوم قاعدة البيانات. ننتقل لإعداد خواديم التطبيقات. إعداد خواديم التطبيقاتتتصل خواديم التطبيق بخادوم قاعدة البيانات. اخترنا ووردبريس للتمثيل في هذا الدليل، وهو تطبيق PHP يعمل على خادوم ويب مثل Apache أو Nginx. سنضبط خادومين متطابقين لتوزيع الحِمل بينهما. تغطّي هذه الفقرة الخطوات الضرورية لإعداد خواديم التطبيق، لكن الموضوع مشروح بتفاصيل أكثر في مقال كيفية إعداد قاعدة بيانات بعيدة لتحسين أداء موقع يستخدِم MySQL انطلاقا من فقرة إعداد خادوم الويب. تثبيت Apache وPHPنفذ الأوامر التالية على كل واحد من الخادومين app1وapp2 لتثبيت Apache وPHP: sudo apt-get update sudo apt-get -y install apache2 php5-mysql php5 libapache2-mod-php5 php5-mcryptإعداد Apacheسنستخدم HAProxy على خادوم موزع الحمل للتعامل مع الاتصال عبر SSL، مما يعني أننا لا نريد أن يتصل المستخدمون بخادوميْ التطبيقات مباشرة. سنربط Apache بعنوان الشبكة الداخلية الخاص بكل واحد من الخادومين. نفّذ الأمر التالي على كل من الخادومين، app1 وapp2: sudo nano /etc/apache2/ports.confابحث عن السطر الذي توجد فيه العبارة Listen 80 وأضف عنوان خادوم التطبيق الخاص إليها، على النحو التالي (أبدل private_IP بعنوان IP الخاص بك): Listen private_IP:80احفظ الملف ثم أغلقه. يجعل هذا الإعداد خادوم Apache يُنصت لعناوين الشبكة الداخلية فقط؛ ممايعني أنه لا يمكن الوصول إليه عبر عنوان IP العمومي أو اسم المستضيف. أعد تشغيل Apache لأخذ التغيير في الحسبان: sudo service apache2 restartلا يمكن - وفق الإعداد الحالي - الوصول مباشرة إلى خادوم Apache؛ إذ تقتصر الاتصالات التي يقبلها على تلك القادمة من الشبكة الداخلية. سنعدّ - بعد قليل - موزع الحمل لإرسال الطلبات إلى الخواديم. تنزيل التطبيق وإعدادهاخترنا في هذه السّلسلة ووردبريس مثالا للتطبيق. إن كنت تستخدم تطبيق PHP مغايرا فيجب عليك تنزيله وعمل الإعدادات اللازمة (معلومات الاتصال بقاعدة البيانات على سبيل المثال)؛ ثم انتقل إلى الفقرة الموالية. نزل أرشيف ووردبريس على خادوم التطبيق الأول، app1: cd ~ wget http://wordpress.org/latest.tar.gzفك ضغط الأرشيف واستخرج ملفات ووردبريس: tar xvf latest.tar.gzانتقل إلى مجلّد ووردبريس المُستخرَج: cd wordpressيحتاج ووردبريس إلى مجلّد لوضع الملفات التي يحملها فيه؛ فلننشئ هذا المجلّد (wp-content/uploads): ode>mkdir wp-content/uploadsسنستخدم ملف إعداد ووردبريس النموذجي قالبا للإعداد: cp wp-config-sample.php wp-config.phpافتح الملف الإعداد من أجل تحريره: nano wp-config.phpاضبط اتصال ووردبريس بقاعدة البيانات بتحرير المعلومات الميَّزة في الأسطر التالية: /** The name of the database for WordPress */ define('DB_NAME', 'app'); /** MySQL database username */ define('DB_USER', 'appuser'); /** MySQL database password */ define('DB_PASSWORD', 'password'); /** MySQL hostname */ define('DB_HOST', 'db1.nyc3.example..com');نضيف الأسطر التالية إلى ملف إعداد ووردبريس لإخباره بأنه خلف وسيط عكسي يستخدم SSL (موزع الحمل يستخدم TLS/SSL للتعميّة): define('FORCE_SSL_ADMIN', true); if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') $_SERVER['HTTPS']='on';احفظ الملف ثم أغلقه. تبقّى الآن نقلُ ملفات ووردبريس إلى مجلد يمكن لخادوم الويب الوصول إليه من أجل خدمة الزوار. نقل ملفات التطبيق إلى جذر المستند Document Rootنحتاج الآن، بعد إعداد التطبيق، لنقل ملفات ووردبريس إلى جذر المستند في Apache حيث يمكن لخادوم الويب الوصول إليها وتقديمها لزوار الموقع. جذر المستند الافتراضي في Apache هو المسار var/www/html/ وهو ما سنستخدمه في مثالنا. احذف أولا ملف index.html الافتراضي: sudo rm /var/www/html/index.htmlاستخدم أداة rsync لنسخ ملفات ووردبريس إلى المجلد var/www/html/ اجعل www-data (الحساب الذي يشتغل به خادوم ويب Apache) مالكَ هذا المجلّد: sudo rsync -avP ~/wordpress/ /var/www/html sudo chgrp -R www-data /var/www/html/*أصبح خادوم التطبيق الأول app1 جاهزا؛ سنعد الآن خادوم التطبيق الآخر. تكرار ملفات التطبيق على الخواديم الأخرىيتوجب إعداد آلية لتكرار الملفات الموجودة في جذر المستند لخادوم الويب على مختلف الخواديم المكوِّنة للتطبيق؛ من أجل إبقاء ملفات التطبيق متجانسة عبر الخواديم. في حالة ووردبريس فإن استخدام واجهة الويب لتحميل الملفات وتثبيت الإضافات سيجعلها موجودة فقط على الخادوم الذي عالج الطلب. إن لم تكرَّر الملفات على جميع الخواديم فسيرى بعض زوار الموقع صفحات بصور ناقصة وإضافات مكسورة. إن كنت تستخدم تطبيقا آخر غير ووردبريس لا يحفظ بياناته (الملفات المحمَّلة والإضافات المنزّلة مثلا) على خادوم التطبيق فيمكنك الاكتفاء بنقل الملفات إلى الخادوم يدويا مرة واحدة. في هذه الحالة استخدم أداة rsync لنقل ملفات التطبيق من الخادوم app1 إلى الخادوم app2. يمكن استخدام GlusterFS لإنشاء تجزئة قرص مكرَّرة من الملفات الضرورية. الطريقة مشروحة في فقرة مزامنة الملفات في تطبيقات الويب ضمن مقال كيف تستخدم HAProxy لتوزيع الحمل بين خواديم تطبيق ووردبريس. اتبع الخطوات (تجاوز فقرة إعداد ملفات المستضيف لأن خادوم النطاقات لدينا يتولى المهمة) ثم اضبُط تكرار الملفات بين app1 وapp2. بعد الانتهاء من إعداد تكرار الملفات بين الخواديم نكون على استعداد لتجهيز موزِّع الحمل. إعداد موزع الحملاخترنا HAProxy موزعا للحمل؛ وسيعمل وسيطا عكسيا لخواديم التطبيق. سيصل المستخدمون إلى التطبيق عبر عنوان شبيه بhttps://www.example.com بعد المرور بموزع الحمل. تشرح هذه الفقرة الخطوات الضرورية لإعداد خادوم موزِّع للحمل/ نسخ شهادة SSLنفذ الخطوات التالية على خادوم موزع الحمل، lb1. ضع شهادة SSL (أحد متطلبات الجزء الأول من السّلسلة) ومفتاح الشهادة، إضافة لأي شهادات من سلطة وسيطة ضمن ملف pem. واحد (نفترض أن شهادات SSL موجودة في المجلّد root/certs/): cd /root/certs cat www.example.com.crt CAintermediate.ca-bundle www.example.com.key > www.example.com.pemثم انسخ ملف pem إلى المجلّد etc/ssl/private/: sudo cp www.example.com.pem /etc/ssl/private/سيستخدم HAProxy هذا الملف لإنهاء SSL. تثبيت HAProxyنفذ الأوامر التالية على خادوم موزع الحمل، lb1: sudo add-apt-repository ppa:vbernat/haproxy-1.5 sudo apt-get update sudo apt-get -y install haproxyإعداد HAProxyنحتاج لضبط إعداداتٍ عامة في HAProxy إضافة لإنهاء SSL والنهايات الخلفية Backend والأمامية Frontend المناسبة لجعله يعمل مع خواديم التطبيق. افتح ملف إعداد HAProxy لتحريره: sudo nano /etc/haproxy/haproxy.cfgخيارات عامة في إعداد HAProxyأول ما يجب فعله هو تحديد قيمة معقولة للحد الأعلى لعدد الاتصالات maxconn. يحدد هذا المتغير عدد الاتصالات الأكبر التي يسمح بها HAProxy في نفس الوقت؛ وهو ما قد يؤثر على جودة الخدمة ويحول دون انهيار خادوم الويب عند محاولته الإجابة على الكثير من الطلبات. يجب أن تبحث وتجرب قيما عدة لإيجاد تلك المناسبة لبيئة عملك. أضف السطر التالي إلى ملف إعداد HAProxy (اخترنا القيمة 2048): maxconn 2048أضف السطر التالي لضبط الحجم الأكبر للذاكرة المؤقتة لتخزين مفاتيح التعمية: tune.ssl.default-dh-param 2048أضف السطرين التاليين ضمن مقطع defaults مباشرة بعد السطر الذي توجد به mode http: option forwardfor option http-server-closeتفعل الأسطر التالية إذا أضيفت ضمن مقطع defaults صفحة إحصاءات HAProxy (أبدل user وpassword بقيم آمنة): stats enable stats uri /stats stats realm Haproxy\ Statistics stats auth user:passwordيمكن بعد التفعيل عرض إحصاءات HAProxy بالذهاب إلى الصفحة التالية https://www.example.com/stats. لم ننته بعد من ملف إعدادات HAProxy، سنضبط في ما يلي إعدادات الوسيط. إعداد الوسيط في HAProxyنبدأ بإضافة نهاية أمامية للتعامل مع اتصالات HTTP الواردة. نضيف في نهاية ملف الإعداد نهاية أمامية باسم www-http عبر الأسطر التالية: frontend www-http bind www.example.com:80 reqadd X-Forwarded-Proto:\ http default_backend app-backendالهدف من هذا الإعداد هو قبول اتصالات HTTP من أجل توجيهها عبر اتصال HTTPS. ثم نضيف نهاية أمامية للتعامل مع اتصالات HTTPS، تأكد من تحديد ملف pem المناسب. frontend www-https bind www.example.com:443 ssl crt /etc/ssl/private/www.example.com.pem reqadd X-Forwarded-Proto:\ https default_backend app-backendنستكمل الإعداد بضبط النهاية الخلفية: backend app-backend redirect scheme https if !{ ssl_fc } server app1 app1.nyc3.example.com:80 check server app2 app2.nyc3.example.com:80 checkتحدد النهاية الخلفية خواديم التطبيقات التي يوزَّع بينها الحمل. يطلب السطر: redirect scheme https if !{ ssl_fc } توجيه اتصالات HTTP إلى HTTPS. احفظ ملف haproxy.cfg ثم أغلقه. HAProxy جاهز الآن لبدء العمل؛ لكن سنفعل أولا السجلات Logs. تفعيل سجلات HAProxyافتح ملف rsyslog للتحرير: sudo nano /etc/rsyslog.confابحث عن الأسطر التالية وانزع علامة التعليق من أجل تفعيل بروتوكول UDP عند استقبال سجلات النظام Syslog. تبدو الأسطر كما يلي بعد نزع علامة التعليق: $ModLoad imudp $UDPServerRun 514 $UDPServerAddress 127.0.0.1أعد تشغيل خدمة rsyslog لتفعيل الإعداد الجديد: sudo service rsyslog restartسجل HAProxy مفعَّل الآن وسيُنشأ ملف var/log/haproxy.log/ فور بدء عمل HAProxy. إعادة تشغيل HAProxyأعد تشغيل HAProxy لأخذ التعديلات في الحسبان. sudo service haproxy restartاكتمل الآن إعداد موزع الحِمل، ننتقل لتثبيت التطبيق (ووردبريس). تثبيت ووردبريسسيتوجب علينا - قبل البدء في استخدام ووردبريس - تشغيل سكربت التثبيت الذي يهيئ قاعدة البيانات ليستخدمها ووردبريس. أدخل إلى العنوان التالي في المتصفح: https://www.example.com/wp-admin/install.phpستظهر شاشة تثبيت ووردبريس. املأء الحقول بما يناسب ثم انقر على زر التثبيت. بعد انتهاء تثبيت ووردبريس يصبح التطبيق جاهزا للعمل. خاتمةاكتمل الآن إعداد الخواديم المكوِّنة للتطبيق، وهذا الأخير جاهز للاستخدام. يمكنك الدخول بحساب المدير كما يمكن لزوار موقعك الوصول إليه عبر HTTPS عند استخدام اسم النطاق المناسب. تأكد قبل الانتقال إلى الجزء الموالي من الدليل أن التطبيق يعمل بطريقة صحيحة. ترجمة -وبتصرّف- لمقال Building for Production: Web Applications — Deploying لصاحبه Mitchell Anicas. حقوق الصورة البارزة: Designed by Freepik.
-
يعرض هذا الدّرس والذي يُعتبر الأول من سلسلة ذات ستة أجزاء كيفية إعداد بنية تحتية لتطبيق مكوَّن من خواديم عدة، انطلاقا من الصفر. سيحتوي الإعداد النهائي على آليات للنسخ الاحتياطي Backup، المراقبة Monitoring، نُظُم مركزية للسجلات Centralized logging مما يعزز من إمكانية تشخيص المشاكل واستعادة إعدادات التطبيق عند الحاجة. الهدف الأسمى هو إنشاء نظام إدارة قائم بذاته، والتعريف بأهم المفاهيم والاعتبارات العملية التي ينبغي التنبه لها عند إعداد خادوم موجَّه للإنتاج Production server. ملحوظة: توجد -عادة- أثناء تطوير وإعداد البرامج بيئة إنتاج وبيئة اختبار (أو أكثر). في بيئة الاختبار يستخدم قليلون التطبيق، ويكون المستخدمون في هذه الحالة غالبا مطورين يبحثون عن علل لترقيعها. في الجانب الآخر فإن التطبيق في بيئة الإنتاج يستخدمه المستهدَفون الحقيقيون بالمنتَج (التطبيق)؛ لذا يجب أن يعمل بكفاءة وسلاسة. قراءة الدّرس التالي وفهمه سيساعدك في المضي قدما مع هذا الدّرس: خمسة إعدادات شائعة لتطبيقات الوب.يقدم المقال خطوطا عريضة لإعداد تطبيق موجَّه للإنتاج، بينما يوضح هذا الدّرس كيفية التخطيط لتطبيق نموذجي وإعداده من البداية إلى النهاية. المأمول هو أن يساعدك الدرس في التخطيط لإعداد خادومك الخاص ثم تنفيذ الإعداد حتى ولو كنت تشغِّل حزمة تطبيقات مختلفة تماما. يحيل الدّرس في أحيان كثيرة، نظرا لأنه يغطي مواضيع مختلفة من إدارة النظم، إلى شروحات مفصلة ضمن مقالات أخرى تقدم معلومات إضافية. الهدفسنحصل بنهاية مجموعة المقالات هذه على خادوم إنتاج معدّ لتشغيل تطبيق PHP، ووردبريس على سبيل المثال، يمكن الوصول إليه عبر العنوان https://www.example.com/. سنعدّ أيضا خواديم إضافية لدعم خواديم التطبيق في بيئة الإنتاج. سيبدو الإعداد النهائي على النحو التالي (لا تظهر خواديم نظام إدارة النطاقات DNS الداخلية ولا النسخ الاحتياطية البعيدة في الصورة أدناه): نعُدُّ الخواديم الموجودة في مربع التطبيق ضرورية ليعمل التطبيق على النحو المرجو. تعمل العناصر المتبقية - النسخ الاحتياطية، المراقبة، والسجلات - بجانب خطة الاستعادة وخادوم النسخ الاحتياطي البعيد؛ على دعم خادوم الإنتاج. سنثبت كل عنصر على خادوم Ubuntu 14.04 منفصل ضمن نفس الحيز الجغرافي مع تفعيل التشبيك الخاص Private networking. نستخدم أسماء المستضيفات Hostnames لتمييز الخواديم المكوِّنة للتطبيق: lb1: موزع الحمل HAProxy، يمكن الوصول إليه عبر العنوان https://www.example.com/.app1: خادوم تطبيقات Apache و PHP.app2: خادوم تطبيقات Apache و PHP.db1: خادوم لقاعدة بيانات MySQL.من المهم التنبيه إلى أنه تم اختيار هذا النوع من الإعداد لتوضيح كيف يمكن لعناصر تطبيق أن تُنشأ على خواديم عدة؛ يجب أن يُخصَّص إعداد تطبيقك بناء على احتياجاتك. توجد نقطة إخفاق Point of failure وحيدة في هذا الإعداد، ويمكن التغلب عليها بتركيب موزع حمل إضافي (وخادوم DNS دوري) ومضاعفة قاعدة البيانات؛ وهو ما لن تطرق إليه في هذا الدرس. نميز العناصر الداعمة للتطبيق بأسماء المستضيفات التالية: النسخ الاحتياطية backups: خادوم النسخ الاحتياطي Bacula.المراقبة monitoring: خادوم Nagios.السجلات logging: سجلات مركزية باستخدام حزمة برمجيات مكونة من Kibana (ELK)، Logstash و Elasticsearch.توجد عناصر أخرى لا تظهر في الصورة، وهي: ns1: وهو خادومنا الرئيس لنظام أسماء النطاقات. نستخدم Bind لهذا الغرض.ns2: وهو الخادوم الثانوي لنظام أسماء النطاقات. نستخدم Bind.remotebackups: خادوم بعيد يوجد في منطقة جغرافية أخرى نحفظ عليه نسخ Bacula الاحتياطية احترازا من كارثة تحل بمركز البيانات الذي يوجد فيه التطبيق.يمكنك أيضا استخدام عنوان IP عائم Floating IP؛ وهو عبارة عن عنوان IP ثابت يُتاح للعموم الوصول إليه ويمكن توجيهه إلى أحد خواديمك الافتراضية أو بنيتك التحتية المكرَّرة Redundant ثم إطلاق موقعك أو خدمتك باستخدام عنوان IP عمومي وحيد. يمكن بعدها إعادة توجيه العنوان العائم إلى خادوم جديد من أجل بيئة إنتاج أكثر مرونة وأسرع تجاوبا. سنضع أيضا خطط استعادة لكلٍّ من العناصر المكونة للتطبيق. ستكون لدينا، عند بلوغ الهدف النهائي، عشرة خواديم. سننشئها كلَّها في نفس الوقت لتسهيل بعض الأمور مثل إعداد النطاقات؛ ولكن يمكنك إنشاؤها الواحد تلو الآخر حسب الحاجة. شبكة خاصة افتراضية Virtual Private Network (اختياري)إذا أردت تأمين اتصالات الشبكة بين خواديمك فيجب عليك إعداد شبكة خاصة افتراضية VPN. يصبح تأمين نقل البيانات عبر الشبكة بتعميتها Encryption أكثر أهمية إذا كانت البيانات تمر عبر الإنترنت. من منافع استخدام شبكة خاصة افتراضية التحقق من هوية المستضيفات بالاستيثاق منها؛ وهو ما يحمي من المصادر التي لا يُرخص لها الوصول للخدمات. إذا كنت تبحث عن أداة مفتوحة المصدر فيمكنك استخدام OpenVPN واتباع خطوات درس دليلك لكيفية إعداد خادوم OpenVPN على Ubuntu لإعداده. المتطلباتيتوجب أن يكون لدى كل خادوم أوبنتو 14.04 حساب مستخدم بصلاحيات إدارية غير المستخدم الجذر؛ يمكن إعداد مستخدم لهذا الغرض باتّباع الخطوات المشروحة في مقال الإعداد الابتدائي لخادوم أوبنتو 14.04. سننفّذ كل الأوامر باستخدام هذا الحساب. سنفترض أيضا أن لديك معرفة بالمفاهيم الأساسية للأمان في لينكس. إذا رغبت في درس تمهيدي حول الموضوع فيمكن الاطلاع على مقال 7 تدابير أمنيّة لحماية خواديمك. اسم نطاقنفترض في هذا المقال أن الوصول إلى التطبيق يكون عبر اسم نطاق، example.com مثلا. إنْ لم يكن لديك اسم نطاق فبالإمكان شراء واحد من أحد مسجلي أسماء النطاقات Domain name registrar. نحتاج اسم النّطاق ليس فقط لتسهيل الوصول إلى الموقع (مقارنة بعنوان IP المكون من أرقام فقط) بل أيضا للحصول على فوائد التحقق من الهوية والنطاق؛ وهو ما يتيح إمكانية الاستفادة من شهادات SSL التي تعمّي البيانات المنقولة بين التطبيق ومستخدميه. شهادة SSLيعمل بروتوكول TLS/SSL على تعميّة البيانات والتحقق من نطاقها أثناء الاتصال بين التطبيق ومستخدميه؛ لذا سنستخدم شهادة SSL لإضافة هذا الإعداد. في المثال نريد أن يصل المستخدمون إلى الموقع عبر العنوان www.example.com وهي القيمة التي سنحددها في الاسم الشّائع للشهادة Common Name (أو ما يُعرف اختصارًا بـ CN). سنثبت الشهادة على خادومHAProxy (المُسمّى lb1) وهو ما يعني أنه من الأفضل توليد مفاتيح الشهادة وطلب توقيع الشهادة Certificate Signing Request CSR على هذا الخادوم. إذا احتجت للتحقق من الهوية فستحتاج لشراء شهادة SSL. توجد الكثير من سلطات الشهادات Certificate Authorities التجارية التي يمكن شراء شهادة SSL منها. كما توجد إمكانية لاستخدام شهادة مجانية من StartSSL يتوفر أيضا حل بديل يتمثل في التوقيع الذاتي لشهادة SSL بتنفيذ الأمر التالي: sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ~/www.example.com.key -out ~/www.example.com.crtالخطوات المتبعة للوصول إلى الهدفعرضنا في الفقرات السابقة نظرة عامة على إعداد تطبيقنا الموجَّه للإنتاج، ننتقل الآن لإنشاء خطة عامة نسير وفقها لتحقيق هدفنا. العناصر الأهم هي تلك التي يتكون منها التطبيق؛ لذا يجب أن نشغلها مبكرا. لكن نظرا لأننا نخطط لاستخدام عنونة تعتمد على أسماء النطاقات للاتصالات ضمن الشبكة الخاصة فيجب أن نعد نظام أسماء النطاقات أولا. سنعدّ، بعد الانتهاء من ضبط إعداد النطاقات، الخواديم التي تكون التطبيق من أجل أن يكون جاهزا للتشغيل. يحتاج التطبيق إلى أن تكون قاعدة بيانات مهيَّأة سلفا، كما يتطلب موزع الحِمل أن يكون التطبيق جاهزا. انطلاقا من هذه الاعتبارات فإن إعداد العناصر سيكون حسب الترتيب التالي: خادوم قاعدة البيانات.خواديم التطبيق.موزع الحمل.سيمكننا - بعد إكمال الخطوات السالفة الذكر من أجل إعداد التطبيق - استنباطُ خطة للاستعادة اعتمادا على سيناريوهات عدة. ستكون خطة الاستعادة أساسية في التخطيط لآليات النسخ الاحتياطي. بعد خطة الاستعادة يأتي دور إعداد النسخ الاحتياطي ثم بعد استكماله يمكن ضبط نظام المراقبة من أجل التأكد من أن جميع الخواديم وكل الخدمات في وضعيةِ عمل مقبولة. ثم نأتي للخطوة الأخيرة وهي إنشاء نظام مركزي لتخزين السجلات مما يسمح بعرضها عند الحاجة، تشخيص المشاكل عند حدوثها وتحليلها لتحديد أنواع الاستخدام وطبيعته. خاتمةخطة العمل جاهزة الآن مما يعني أننا جاهزون للبدء في تنفيذ إعدادات التطبيق. ينبغي تذكر أن هذا الإعداد، رغم أنه يعمل على النحو المراد، يبقى مثالا يجب أن تستطيع التقاط معلومات مفيدة منه ثم استخدام ما تعلمته لتحسين إعداد تطبيقك الخاص. ترجمة -وبتصرّف- لمقال Building for Production: Web Applications — Overview لصاحبه Mitchell Anicas. حقوق الصورة البارزة: Designed by Freepik.
-
- 1
-
- نطاق
- load balancing
-
(و 6 أكثر)
موسوم في: