تلعب عملية أتمتة الخادم server automation الآن دورًا أساسيًا في إدارة الأنظمة نظرًا لطبيعة بيئات التطبيقات الحديثة التي تُستخدَم لمرة واحدة ثم يمكنك التخلص منها، إذ تُستخدَم أدوات إدارة الضبط Configuration management مثل أداة Ansible لتبسيط عملية إعداد الخادم من خلال إنشاء إجراءات معيارية للخوادم الجديدة، مما يقلل من الأخطاء البشرية المرتبطة بالإعدادات اليدوية. لذا تقدّم أداة Ansible معمارية مبسَّطة لا تتطلب تثبيت برامج خاصة على العُقد، وتوفر مجموعة من الميزات والوحدات المبنية مسبقًا والتي تسهل كتابة سكربتات الأتمتة.
سيوضح هذا المقال كيفية إعداد ملف المخزون Inventory File وتنفيذ مجموعة من سكربتات الإعداد المسبَق Provisioning لأتمتة عملية إعداد خادم حزمة LEMP أو (Linux و (E)nginx و MariaDB و PHP-FPM) على أوبنتو ونشر تطبيق لارافيل Laravel التجريبي على هذا النظام.
ملاحظة: يهدف هذا المقال إلى توضيح كيفية استخدام أدلة التشغيل Playbooks لأتمتة إعداد الخادم باستخدام أداة Ansible، ونشجعك على تعديل وتكييف الإعداد المضمَّن ليناسب احتياجاتك الخاصة بالرغم من أننا سنستخدم تطبيق لارافيل الذي يعمل على خادم LEMP.
المتطلبات الأساسية
ستحتاج ما يلي لمتابعة هذا المقال:
- عقدة تحكم Ansible واحدة: وهي جهاز يعمل بنظام أوبنتو 22.04 مع تثبيت أداة Ansible عليه وضبطه للاتصال بمضيفات Ansible باستخدام مفاتيح SSH. تأكّد من أن عقدة التحكم لديها مستخدم عادي يمتلك أذونات مستخدم sudo (أذونات المستخدم الجذر) مع تفعيل جدار حماية، وتعلّم كيفية تثبيت وضبط Ansible على أوبنتو لإعداد الأداة Ansible.
-
مضيف Ansible واحد أو أكثر: هو خادم أوبنتو واحد أو أكثر، إذ يجب أن يكون لكل مضيفٍ المفتاح العام لعقدة التحكم الذي يُضاف إلى ملف
authorized_keys
. إن أردتَ استخدام أجهزة DigitalOcean Droplets الافتراضية بوصفها عقدًا، فيمكنك استخدام لوحة التحكم لإضافة مفتاحك العام إلى مضيفات Ansible.
الخطوة الأولى: نسخ المستودع التجريبي
يجب أولًا نسخ المستودع الذي يحتوي على سكربتات Ansible للإعداد المسبَق وتطبيق لارافيل التجريبي الذي سننشره على الخوادم البعيدة، حيث يمكن العثور على جميع الملفات الضرورية في مستودع جيت هَب do-community/ansible-laravel-demo.
انسخ المستودع بعد تسجيل الدخول إلى عقدة تحكم Ansible كمستخدم جذر sudo، وانتقل إلى المجلد الذي ينشئه الأمر git
كما يلي:
git clone https://github.com/do-community/ansible-laravel-demo.git cd ansible-laravel-demo
يمكنك الآن تشغيل الأمر ls
لفحص محتويات المستودع المنسوخ كما يلي:
ls -l --group-directories-first
وسترى خرجًا يشبه التالي:
drwxrwxr-x 3 sammy sammy 4096 Mar 24 15:24 application drwxrwxr-x 2 sammy sammy 4096 Mar 24 15:24 group_vars drwxrwxr-x 7 sammy sammy 4096 Mar 24 15:24 roles -rw-rw-r-- 1 sammy sammy 102 Mar 24 15:24 inventory-example -rw-rw-r-- 1 sammy sammy 1987 Mar 24 15:24 laravel-deploy.yml -rw-rw-r-- 1 sammy sammy 794 Mar 24 15:24 laravel-env.j2 -rw-rw-r-- 1 sammy sammy 920 Mar 24 15:24 readme.md -rw-rw-r-- 1 sammy sammy 318 Mar 24 15:24 server-setup.yml
إليك نظرة عامة على المجلدات والملفات السابقة:
-
application/
: يحتوي هذا المجلد على تطبيق لارافيل التجريبي الذي سننشره على الخادم البعيد في النهاية. -
group_vars/
: يحتوي هذا المجلد على ملفات المتغيرات التي تحتوي على خيارات مُخصَّصة لإعداد التطبيق مثل ثبوتيات Credentials قاعدة البيانات ومكان تخزين ملفات التطبيق على الخادم البعيد. -
roles/
: يحتوي هذا المجلد على أدوار Ansible المختلفة التي تعالج الإعداد المسبَق لخادم Ubuntu LEMP. -
inventory-example
: يمكن استخدام هذا الملف بوصفه قاعدةً لإنشاء مخزون مُخصَّص لبنيتك التحتية. -
laravel-deploy.yml
: دليل التشغيل الذي سينشر تطبيق لارافيل التجريبي على الخادم البعيد. -
laravel-env.j2
: يستخدم دليلُ التشغيلlaravel-deploy.yml
هذا القالب لإعداد ملف بيئة التطبيق. -
readme.md
: يحتوي هذا الملف على معلومات عامة حول الإعداد المسبَق المتضمن في هذا المستودع. -
server-setup.yml
: سيُعِدّ دليل التشغيل هذا مسبقًا خادم LEMP باستخدام الأدوار المُحدَّدة في المجلدroles/
.
الخطوة الثانية: إعداد ملف المخزون واختبار الاتصال بالعقد
سننشئ الآن ملف مخزون لسرد المضيفين الذين نريد إدارتهم باستخدام أداة Ansible. انسخ أولًا الملف inventory-example
إلى ملف جديد يسمى hosts
:
cp inventory-example hosts
استخدم محرر النصوص الذي تريده لفتح ملف المخزون الجديد وحدّثه باستخدام خوادمك الخاصة، إذ سنستخدم في مثالنا محرر النصوص nano
:
nano hosts
يحتوي المخزون في مثالنا على مجموعتين هما: التطوير dev
والإنتاج production
اللتان توضحان كيفية استخدام متغيرات المجموعة لتخصيص النشر في بيئات متعددة. إذا أردتَ اختبار هذا الإعداد باستخدام عقدة واحدة، فيمكنك استخدام إما مجموعة التطوير dev
أو مجموعة الإنتاج production
وإزالة المجموعة الأخرى من ملف المخزون.
[dev] 203.0.113.0.101 [prod] 203.0.113.0.102 [all:vars] ansible_python_interpreter=/usr/bin/python3
ملاحظة: يحدّد المتغير ansible_python_interpreter
المسار إلى ملف بايثون التنفيذي على المضيف البعيد، ونطلب هناك من أداة Ansible أن تضبط هذا المتغير لجميع المضيفات في ملف المخزون.
احفظ وأغلق الملف عند الانتهاء، فإذا أردتَ استخدام محرر النصوص nano
، فيمكنك ذلك عن طريق الضغط على الاختصار "CTRL+X" ثم نضغط "Y" وزر الادخال "ENTER" للتأكيد.
يمكنك بعد الانتهاء من ضبط ملف المخزون تنفيذ وحدة ping
الخاصة بالأداة Ansible لاختبار ما إذا كانت عقدة التحكم قادرة على الاتصال بالمضيفين كما يلي:
ansible all -i hosts -m ping -u root
لنتعرّف على الأمر السابق بالتفصيل:
-
all
: يخبر هذا الخيار أداة Ansible بتشغيل الأمر الذي يليه على جميع المضيفات من ملف المخزون المحدَّد. -
-i hosts
: يحدد المخزون الذي يجب استخدامه، وإن لم يتوفّر هذا الخيار، فستحاول أداة Ansible استخدام المخزون الافتراضي الذي يوجد عادةً في المجلد/etc/ansible/hosts
. -
-m ping
: سيؤدي هذا الأمر إلى تنفيذ وحدةping
الخاصة بأداة Ansible، والتي ستختبر الاتصال بالعقد وما إذا كان يمكن العثور على ملف بايثون التنفيذي على الأنظمة البعيدة أم لا. -
-u root
: يحدّد هذا الخيار المستخدم البعيد الذي يجب استخدامه للاتصال بالعقد، إذ نستخدم حساب الجذر في مثالنا لأنه الحساب الوحيد المتاح على خوادم جديدة. يمكن أن تكون خيارات الاتصال الأخرى ضرورية بناءً على مزود البنية التحتية وضبط SSH.
إذا ضُبِط اتصال SSH بالعقد بصورة صحيحة، فستحصل على الخرج التالي:
203.0.113.0.101 | SUCCESS => { "changed": false, "ping": "pong" } 203.0.113.0.102 | SUCCESS => { "changed": false, "ping": "pong" }
تعني الاستجابة pong
أن عقدة التحكم الخاصة بك قادرة على الاتصال بالعقد المُدارة، وأن أداة Ansible قادرة على تنفيذ أوامر بايثون على المضيفين البعيدين.
الخطوة الثالثة: إعداد ملفات المتغيرات
يجب أولًا قبل تشغيل أدلة التشغيل المُضمَّنة في مثالنا تعديلُ ملف المتغيرات الذي يحتوي على إعدادات مثل اسم المستخدم البعيد الذي سيُنشَأ وثبوتيات قاعدة البيانات لإعدادها باستخدام قاعدة بيانات MariaDB.
افتح الملف group_vars/all
باستخدام محرر النصوص الذي تريده كما يلي:
nano group_vars/all.yml
يحتوي هذا الملف على المحتويات التالية:
--- # Initial Server Setup remote_user: sammy # MySQL Setup mysql_root_password: MYSQL_ROOT_PASSWORD mysql_app_db: travellist mysql_app_user: travellist_user mysql_app_pass: DB_PASSWORD # Web Server Setup http_host: "{{ ansible_facts.eth0.ipv4.address }}" remote_www_root: /var/www app_root_dir: travellist-demo document_root: "{{ remote_www_root }}/{{ app_root_dir }}/public" # Laravel Env Variables app_name: Travellist app_env: dev app_debug: true app_url: "http://{{ http_host }}" db_host: localhost db_port: 3306 db_database: "{{ mysql_app_db }}" db_user: "{{ mysql_app_user }}" db_pass: "{{ mysql_app_pass }}"
المتغيرات التي يجب معرفتها هي:
-
remote_user
: سيُنشَأ المستخدم المُحدَّد على الخادم البعيد وسيُمنَح صلاحيات المستخدم الجذرsudo
. -
mysql_root_password
: يحدّد هذا المتغير كلمة مرور قاعدة البيانات الجذر لخادم MariaDB، ولاحظ أنه يجب أن تكون كلمة مرور آمنة من اختيارك. -
mysql_app_db
: اسم قاعدة البيانات المُراد إنشاؤها لتطبيق لارافيل. لست بحاجة إلى تغيير هذه القيمة، ولكن لك الحرية في تغييرها إذا أردتَ ذلك، حيث ستُستخدَم هذه القيمة لإعداد ملف ضبط لارافيل.env
. -
mysql_app_user
: اسم مستخدم قاعدة البيانات لتطبيق لارافيل. لست بحاجة إلى تغيير هذه القيمة، ولكن لك الحرية في تغييرها إذا أردتَ ذلك. -
mysql_app_pass
: كلمة مرور قاعدة البيانات لتطبيق لارافيل، إذ يجب أن تكون كلمة مرور آمنة من اختيارك. -
http_host
: اسم النطاق أو عنوان IP للمضيف البعيد. نستخدم في مثالنا حقيقة Fact خاصة بأداة Ansible التي تحتوي على عنوان IPv4 لواجهة الشبكةeth0
. إذا كان هناك أسماء نطاقات تؤشّر إلى مضيفاتك البعيدة، فيمكن أن ترغب في إنشاء ملفات متغيرات منفصلة لكل منها، وتعديل هذه القيمة ليحتوي ضبطُ خادم Nginx على اسم المضيف الصحيح لكل خادم.
احفظ الملف وأغلقه عندما تنتهي من تعديل هذه القيم.
إنشاء ملفات متغيرات إضافية لبيئات متعددة
إذا أعددتَ ملف المخزون مع عقد متعددة، فيمكن أن ترغب في إنشاء ملفات متغيرات إضافية لإعداد كل عقدة وفقًا لذلك، حيث أنشأنا في مثالنا مجموعتين متميزتين للمخزون هما: التطوير dev
والإنتاج production
، إذ يجب إنشاء ملف متغيرات منفصل للاحتفاظ بقيم الإنتاج لتجنب وجود ثبوتيات قاعدة البيانات والإعدادات الأخرى نفسها في كلتا البيئتين.
يمكن أن ترغب في نسخ ملف المتغيرات الافتراضي واستخدامه بوصفه قاعدةً لقيم الإنتاج الخاصة بك كما يلي:
cp group_vars/all.yml group_vars/production.yml nano group_vars/production.yml
يحتوي ملف all.yml
على القيم الافتراضية التي يجب أن تكون صالحة لجميع البيئات، لذا يمكنك إزالة جميع المتغيرات التي لن تحتاج إلى تغييرها من ملف production.yml
الجديد. المتغيرات التي يجب تحديثها لكل بيئة هي:
-
prod_user
-
MYSQL_PROD_ROOT_PASSWORD
-
MYSQL_PROD_APP_PASSWORD
-
prod
-
false
وذلك في الشيفرة التالية:
--- # Initial Server Setup remote_user: prod_user # MySQL Setup mysql_root_password: MYSQL_PROD_ROOT_PASSWORD mysql_app_pass: MYSQL_PROD_APP_PASSWORD # Laravel Env Variables app_env: prod app_debug: false
لاحظ أننا غيّرنا قيمة app_env
إلى prod
وضبطنا قيمة app_debug
على false
، وهذه هي إعدادات لارافيل الموصَى بها لبيئات الإنتاج.
احفظ الملف وأغلقه بعد الانتهاء من تخصيص متغيرات الإنتاج.
تشفير ملفات المتغيرات باستخدام ميزة Vault الخاصة بأداة Ansible
إذا أردت مشاركة إعداد أداة Ansible الخاص بك مع مستخدمين آخرين، فيجب الحفاظ على أمان ثبوتيات قاعدة البيانات والبيانات الحساسة الأخرى في ملفات المتغيرات، ويمكن تحقيق ذلك باستخدام ميزة Vault الخاصة بأداة Ansible، وهي ميزة مُضمَّنة فيها افتراضيًا، إذ تسمح هذه الميزة بتشفير ملفات المتغيرات بحيث يتمكن فقط المستخدمون الذين لديهم إذن الوصول إلى كلمة مرور Vault من عرض هذه الملفات أو تعديلها أو إلغاء تشفيرها. تُعَد كلمة مرور Vault ضرورية لتشغيل دليل التشغيل أو الأمر الذي يستخدم الملفات المُشفَّرة.
شغّل الأمر التالي لتشفير ملف متغيرات الإنتاج:
ansible-vault encrypt group_vars/production.yml
سيُطلَب منك تقديم كلمة مرور Vault وتأكيدها، ثم سترى أن البيانات مُشفَّرة إذا فحصتَ محتويات هذا الملف. إذا أردتَ عرض ملف المتغيرات دون تغيير محتوياته، فيمكنك استخدام أمر view
التالي:
ansible-vault view group_vars/production.yml
سيُطلَب منك تقديم كلمة المرور نفسها التي حددتها عند تشفير هذا الملف باستخدام ansible-vault
، ثم ستظهر محتويات الملف في طرفيتك Terminal بعد تقديم كلمة المرور، ويمكنك الخروج من عرض الملف من خلال الضغط على q
.
استخدم الأمر edit
التالي لتعديل ملف مُشفَّر مسبقًا باستخدام Ansible Vault:
ansible-vault edit group_vars/production.yml
سيطلب منك هذا الأمر تقديم كلمة مرور Vault لهذا الملف، ثم سيُستخدَم محرّر طرفيتك الافتراضي لفتح الملف لتعديله. احفظ الملف وأغلقه بعد إجراء التغييرات المطلوبة، وسيُشفَّر تلقائيًا مرة أخرى باستخدام Ansible Vault.
انتهيت الآن من إعداد ملفات المتغيرات، وسنشغّل في الخطوة التالية دليل التشغيل لإعداد Nginx و PHP-FPM و MariaDB (والتي تشكل مع نظام التشغيل المستند إلى لينكس مثل أوبنتو حزمة LEMP) على الخادم أو الخوادم البعيدة.
الخطوة الرابعة: تنفيذ دليل تشغيل حزمة LEMP
يجب إعداد بيئة LEMP التي تخدّم التطبيق قبل نشر تطبيق لارافيل التجريبي على الخادم أو الخوادم البعيدة، إذ يتضمن دليل التشغيل server-setup.yml
أدوار Ansible الضرورية لإعدادها. يمكنك فحص محتويات دليل التشغيل server-setup.yml
من خلال تشغيل الأمر التالي:
cat server-setup.yml
وسيظهر الخرج التالي:
--- - hosts: all become: true roles: - { role: setup, tags: ['setup'] } - { role: mariadb, tags: ['mysql', 'mariadb', 'db', 'lemp'] } - { role: php, tags: ['php', 'web', 'php-fpm', 'lemp'] } - { role: nginx, tags: ['nginx', 'web', 'http', 'lemp'] } - { role: composer, tags: ['composer'] }
إليك نظرة عامة على جميع الأدوار المضمنة في دليل التشغيل السابق:
-
setup
: يحتوي على المهام اللازمة لإنشاء مستخدم جديد للنظام ومنحه صلاحيات المستخدم الجذرsudo
بالإضافة إلى تفعيل جدار الحمايةufw
. -
mariadb
: يثبّت خادم قاعدة بيانات MariaDB وينشئ قاعدة بيانات ومستخدم التطبيق. -
php
: يثبّت وحداتphp-fpm
و PHP الضرورية لتشغيل تطبيق لارافيل. -
nginx
: يثبّت خادم الويب Nginx ويتيح الوصول إلى المنفذ 80. -
composer
: تثبيت مدير الحزم Composer على المستوى العام.
لاحظ أننا ضبطنا بعض الوسوم ضمن كل دور لتسهيل إعادة تشغيل أجزاء فقط من دليل التشغيل إن لزم الأمر. إذا أجريت تغييرات على ملف قالب Nginx مثلًا، فيمكن أن ترغب في تشغيل الدور Nginx فقط.
سينفّذ الأمر التالي دليل التشغيل على جميع الخوادم من ملف مخزونك، حيث يُعَد --ask-vault-pass
ضروريًا فقط في حالة استخدام ansible-vault
لتشفير ملفات المتغيرات في الخطوة السابقة:
ansible-playbook -i hosts server-setup.yml -u root --ask-vault-pass
وستحصل على خرج يشبه ما يلي:
PLAY [all] ********************************************************************************************** TASK [Gathering Facts] ********************************************************************************** ok: [203.0.113.0.101] ok: [203.0.113.0.102] TASK [setup : Install Prerequisites] ******************************************************************** changed: [203.0.113.0.101] changed: [203.0.113.0.102] ... RUNNING HANDLER [nginx : Reload Nginx] ****************************************************************** changed: [203.0.113.0.101] changed: [203.0.113.0.102] PLAY RECAP ********************************************************************************************** 203.0.113.0.101 : ok=31 changed=27 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1 203.0.113.0.102 : ok=31 changed=27 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
أصبحت عقدتك (أو مجموعة عقدك) جاهزةً الآن لتخديم تطبيقات PHP باستخدام Nginx و PHP-FPM مع خادم قاعدة بيانات MariaDB، وسننشر في الخطوة التالية تطبيق لارافيل التجريبي المُضمَّن باستخدام دليل تشغيل Ansible الذي هو laravel-deploy.yml
.
الخطوة الخامسة: نشر تطبيق لارافيل
أصبح لديك الآن بيئة LEMP تعمل على الخادم أو الخوادم البعيدة، فيمكنك تنفيذ دليل التشغيل laravel-deploy.yml
الذي سينفّذ المهام التالية:
- إنشاء المستند الجذر للتطبيق على الخادم البعيد، إن لم يُنشَأ فعليًا.
-
مزامنة مجلد التطبيق المحلي مع الخادم البعيد باستخدام الوحدة
sync
. -
استخدام الوحدة
acl
لضبط أذونات مستخدم www-data في مجلد التخزين. -
إعداد ملف التطبيق
.env
بناءً على القالبlaravel-env.j2
. - تثبيت اعتماديات التطبيق باستخدام مدير الحزم Composer.
- توليد مفتاح أمان التطبيق.
-
إعداد رابط عام للمجلد
storage
. - تشغيل عمليات تهجير Migration قاعدة البيانات والبذر Seeder.
يجب أن ينفِّذ مستخدمٌ غير جذر لديه أذونات sudo دليلَ التشغيل، ويجب أن يكون هذا المستخدم مُنشَأً عند تنفيذ دليل التشغيل server-setup.yml
في الخطوة السابقة باستخدام الاسم الذي يحدّده المتغير remote_user
.
شغّل دليل التشغيل laravel-deploy.yml
باستخدام الأمر التالي:
ansible-playbook -i hosts laravel-deploy.yml -u sammy --ask-vault-pass
يُعَد --ask-vault-pass
ضروريًا فقط في حالة استخدام ansible-vault
لتشفير ملفات المتغيرات في الخطوة السابقة.
وستحصل على خرج يشبه ما يلي:
PLAY [all] ********************************************************************************************** TASK [Gathering Facts] ********************************************************************************** ok: [203.0.113.0.101] ok: [203.0.113.0.102] TASK [Make sure the remote app root exists and has the right permissions] ******************************* ok: [203.0.113.0.101] ok: [203.0.113.0.102] TASK [Rsync application files to the remote server] ***************************************************** ok: [203.0.113.0.101] ok: [203.0.113.0.102] ... TASK [Run Migrations + Seeders] ************************************************************************* ok: [203.0.113.0.101] ok: [203.0.113.0.102] PLAY RECAP ********************************************************************************************** 203.0.113.0.101 : ok=10 changed=9 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 203.0.113.0.102 : ok=10 changed=9 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
يمكنك عند انتهاء التنفيذ الوصول إلى التطبيق التجريبي من خلال توجيه متصفحك إلى اسم نطاق أو عنوان IP الخاص بعقدتك:
http://node_domain_or_IP
وسترى صفحة تشبه ما يلي:
الخلاصة
أوضح هذا المقال كيفية إعداد ملف مخزون الأداة Ansible والاتصال بالعقد البعيدة، وكيفية تشغيل أدلة تشغيل Ansible لإعداد خادم LEMP ونشر تطبيق لارافيل التجريبي عليه. اطّلع على مستودع جيت هَب التجريبي الذي يحتوي على جميع الملفات الضرورية لمتابعة العمل.
ترجمة -وبتصرُّف- للمقال Automating Server Setup with Ansible: A DigitalOcean Workshop Kit لصاحبته Erika Heidi.
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.