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