اذهب إلى المحتوى

تثبيت وضبط تطبيق لارافيل مع خادم Nginx على حزمة LEMP من أوبنتو


Ola Abbas

يُعَد لارافيل Laravel إطار عمل بلغة PHP، وهو مفتوح المصدر ويوفر مجموعة من الأدوات والموارد لبناء تطبيقات PHP الحديثة. نمت شعبية لارافيل بسرعة في السنوات القليلة الماضية مع وجود نظام بيئي كامل يستفيد من ميزاته المبنية مسبقًا، واعتماد العديد من المطورين له بوصفه إطار العمل المفضل لديهم لعمليات التطوير الفعالة.

سنثبّت ونضبط في هذا المقال تطبيق لارافيل جديد على خادم لينكس أوبنتو Ubuntu 22.04 باستخدام مدير الحزم Composer لتنزيل وإدارة اعتماديات إطار العمل وخادم Nginx لتخديم التطبيق، وسيكون لديك في النهاية تطبيق لارافيل تجريبي عملي يسحب المحتوى من قاعدة بيانات MySQL 8.

المتطلبات الأساسية

يجب أولًا تنفيذ المهام التالية على خادم لينكس أوبنتو:

  • أنشئ مستخدم sudo وفعّل ufw.
  • ثبّت حزمة LEMP مع قاعدة بيانات MySQL 8.
  • ثبّت مدير الحزم Composer الذي سنستخدمه لتثبيت لارافيل واعتمادياته.

الخطوة الأولى: تثبيت وحدات PHP المطلوبة

يجب تثبيت بعض وحدات PHP التي يتطلبها إطار العمل قبل أن تتمكن من تثبيت لارافيل، حيث سنستخدم الأمر apt لتثبيت وحدات PHP، وهي وحدات php-mbstring و php-xml و php-bcmath. توفر هذه التوسّعات الخاصة بلغة PHP دعمًا إضافيًا للتعامل مع تشفير المحارف وتنسيق XML والدقة الرياضية.

إذا كانت هذه هي المرة الأولى التي تستخدم فيها الأمر apt في هذه الجلسة، فيجب عليك أولًا تشغيل أمر update التالي لتحديث جدول الحزم:

sudo apt update

يمكنك الآن تثبيت الحزم المطلوبة باستخدام الأمر التالي:

sudo apt install php-mbstring php-xml php-bcmath

أصبح نظامك جاهزًا لتنفيذ تثبيت لارافيل باستخدام مدير الحزم Composer، ولكن ستحتاج إلى قاعدة بيانات لتطبيقك قبل ذلك.

الخطوة الثانية: إنشاء قاعدة بيانات للتطبيق

سننشئ تطبيق قائمة السفر Travel List الذي يعرض قائمة بالأماكن التي يرغب المستخدم في السفر إليها وقائمة بالأماكن التي زارها فعليًا لتوضيح تثبيت لارافيل واستخدامه الأساسي، حيث يمكن تخزين هذه القوائم في جدول الأماكن Places مع حقل للمواقع التي سنسميه name وحقل آخر لتمييز المواقع بوصفها مُزارة visited أو غير مُزارة not visited، حيث سنسميه هذا الحقل visited، وسنضمّن حقل المعرّف id لتحديد كل إدخال بصورة فريدة. سننشئ مستخدم MySQL مخصص ونمنحه صلاحيات كاملة في قاعدة البيانات travellist للاتصال بقاعدة البيانات من تطبيق لارافيل.

لا تدعم المكتبة mysqlnd -وهي مكتبة MySQL PHP الأصيلة- التابعَ caching_sha2_authentication الذي هو تابع الاستيثاق الافتراضي لقاعدة بيانات MySQL 8، لذا يجب إعداد مستخدم قاعدة البيانات باستخدام تابع الاستيثاق mysql_native_password حتى نتمكّن من الاتصال بقاعدة بيانات MySQL من PHP.

أولًا، سجّل الدخول إلى طرفية MySQL بوصفك مستخدم قاعدة البيانات الجذر باستخدام الأمر التالي:

sudo mysql

شغّل الأمر التالي من طرفية MySQL لإنشاء قاعدة بيانات جديدة:

CREATE DATABASE travellist;

يمكنك الآن إنشاء مستخدم جديد ومنحه الصلاحيات الكاملة في قاعدة البيانات المخصصة التي أنشأتها، حيث سننشئ في مثالنا مستخدم باسم travellist_user مع كلمة مرور password بالرغم من أنه يجب عليك تغييرها إلى كلمة مرور آمنة من اختيارك:

CREATE USER 'travellist_user'@'%' IDENTIFIED WITH mysql_native_password BY 'password';

يجب الآن أن نمنح هذا المستخدم إذنًا في قاعدة بيانات travellist كما يلي:

GRANT ALL ON travellist.* TO 'travellist_user'@'%';

مما يؤدي إلى إعطاء المستخدم travellist_user الصلاحيات الكاملة في قاعدة بيانات travellist، مع منع هذا المستخدم من إنشاء أو تعديل قواعد بيانات أخرى على خادمك.

اخرج بعد ذلك من صدفة MySQL:

exit

يمكنك الآن اختبار ما إذا كان المستخدم الجديد لديه الأذونات المناسبة من خلال تسجيل الدخول إلى طرفية MySQL مرة أخرى باستخدام ثبوتيات المستخدم المخصَّص هذه المرة:

mysql -u travellist_user -p

لاحظ الخيار ‎-p في هذا الأمر، والتي ستطلب كلمة المرور المُستخدَمة عند إنشاء المستخدم travellist_user. تأكد بعد تسجيل الدخول إلى طرفية MySQL من أنه يمكنك الوصول إلى قاعدة بيانات travellist كما يلي:

SHOW DATABASES;

وسيظهر الخرج التالي:

+--------------------+
| Database           |
+--------------------+
| information_schema |
| travellist        |
+--------------------+
2 rows in set (0.01 sec)

أنشئ بعد ذلك جدولًا بالاسم places في قاعدة البيانات travellist من خلال تشغيل التعليمة التالية من طرفية MySQL:

CREATE TABLE travellist.places (
    id INT AUTO_INCREMENT,
    name VARCHAR(255),
    visited BOOLEAN,
    PRIMARY KEY(id)
);

املأ الجدول places ببعض البيانات كما يلي:

INSERT INTO travellist.places (name, visited)
VALUES ("Tokyo", false),
("Budapest", true),
("Nairobi", false),
("Berlin", true),
("Lisbon", true),
("Denver", false),
("Moscow", false),
("Olso", false),
("Rio", true),
("Cincinnati", false),
("Helsinki", false);

شغّل التعليمة التالية لتأكيد حفظ البيانات بنجاح في جدولك:

SELECT * FROM travellist.places;

وسترى خرجًا مشابهًا لما يلي:

+----+-----------+---------+
| id | name      | visited |
+----+-----------+---------+
|  1 | Tokyo     |       0 |
|  2 | Budapest  |       1 |
|  3 | Nairobi   |       0 |
|  4 | Berlin    |       1 |
|  5 | Lisbon    |       1 |
|  6 | Denver    |       0 |
|  7 | Moscow    |       0 |
|  8 | Oslo      |       0 |
|  9 | Rio       |       1 |
| 10 | Cincinnati|       0 |
| 11 | Helsinki  |       0 |
+----+-----------+---------+
11 rows in set (0.00 sec)

يمكنك الخروج من طرفية MySQL بعد التأكد من وجود بيانات صالحة في جدول اختبارك:

exit

أصبحتَ الآن جاهزًا لإنشاء التطبيق وضبطه للاتصال بقاعدة البيانات الجديدة.

الخطوة الثالثة: إنشاء تطبيق لارافيل جديد

ستنشئ الآن تطبيق لارافيل جديد باستخدام الأمر composer create-project، إذ يُستخدَم هذا الأمر لتشغيل التطبيقات الجديدة بناءً على أطر العمل وأنظمة إدارة المحتوى الحالية.

سنستخدم في هذا المقال الاسم travellist للتطبيق، ولكن يمكنك تغييره إلى أي شيء آخر. سيعرض تطبيق travellist قائمةً بالمواقع المسحوبة من خادم MySQL محلي بهدف توضيح ضبط تطبيق لارافيل الأساسي والتأكد من قدرتك على الاتصال بقاعدة البيانات.

انتقل أولًا إلى مجلد المنزل كما يلي:

cd ~

ينشئ الأمر التالي مجلد travellist جديد يحتوي على تطبيق لارافيل هيكلي استنادًا إلى الإعدادات الافتراضية:

composer create-project --prefer-dist laravel/laravel travellist

وسترى خرجًا مشابهًا لما يلي:

Creating a "laravel/laravel" project at "./travellist"
Installing laravel/laravel (v10.1.1)
  - Downloading laravel/laravel (v10.1.1)
  - Installing laravel/laravel (v10.1.1): Extracting archive
Created project in /tmp/travellist
> @php -r "file_exists('.env') || copy('.env.example', '.env');"
Loading composer repositories with package information
Updating dependencies
Lock file operations: 106 installs, 0 updates, 0 removals
  - Locking brick/math (0.11.0)
  - Locking dflydev/dot-access-data (v3.0.2)
  - Locking doctrine/inflector (2.0.6)
  - Locking doctrine/lexer (3.0.0)
  - Locking dragonmantank/cron-expression (v3.3.2)
  - Locking egulias/email-validator (4.0.1)
...

انتقل إلى مجلد التطبيق عند انتهاء التثبيت وشغّل أمر لارافيل artisan للتحقق من تثبيت جميع المكونات بنجاح:

cd travellist
php artisan

وسترى خرجًا مشابهًا لما يلي:

Laravel Framework 10.9.0

Usage:
  command [options] [arguments]

Options:
  -h, --help            Display this help message
  -q, --quiet           Do not output any message
  -V, --version         Display this application version
      --ansi            Force ANSI output
      --no-ansi         Disable ANSI output
  -n, --no-interaction  Do not ask any interactive question
      --env[=ENV]       The environment the command should run under
  -v|vv|vvv, --verbose  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
...

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

الخطوة الرابعة: ضبط تطبيق لارافيل

توجد ملفات ضبط لارافيل في مجلد بالاسم config ضمن المجلد الجذر للتطبيق، وإذا ثَبّتَ لارافيل باستخدام مدير الحزم Composer، فسينشئ ملف بيئة Environment File، حيث يحتوي هذا الملف على إعدادات خاصة بالبيئة الحالية التي يعمل بها التطبيق، وستكون لها الأفضلية على القيم المحددة في ملفات الضبط العادية الموجودة في المجلد config. يتطلب كل تثبيت في بيئة جديدة ملف بيئة مخصص لتعريف أشياء مثل إعدادات اتصال قاعدة البيانات وخيارات تنقيح الأخطاء وعنوان URL للتطبيق وعناصر أخرى تختلف اعتمادًا على البيئة التي يعمل بها التطبيق.

تحذير: يحتوي ملف ضبط البيئة على معلومات حساسة حول خادمك، بما في ذلك ثبوتيات قاعدة البيانات ومفاتيح الأمان، لذلك لا يجب أبدًا مشاركة هذا الملف علنًا.

سنعدّل ملف ‎.env لتخصيص خيارات الضبط لبيئة التطبيق الحالية. افتح ملف ‎.env باستخدام محرر سطر الأوامر الذي تختاره، حيث سنستخدم هنا nano:

nano .env

توجد العديد من متغيرات الضبط في هذا الملف، ولكنك لن تحتاج إلى إعدادها جميعًا الآن. تحتوي القائمة التالية على نظرة عامة على المتغيرات التي يجب الاهتمام بها:

  • APP_NAME: اسم التطبيق المُستخدَم للإشعارات والرسائل.
  • APP_ENV: بيئة التطبيق الحالية.
  • APP_KEY: يُستخدم لتوليد السلاسل النصية الإضافية Salts والقيم المُعمَّاة المختصَرة Hashes، ويُنشَأ هذا المفتاح الفريد تلقائيًا عند تثبيت لارافيل باستخدام مدير الحزم Composer، لذلك لا حاجة إلى تغييره.
  • APP_DEBUG: يحدد إظهار معلومات تنقيح الأخطاء من طرف العميل أم لا.
  • APP_URL: عنوان URL الأساسي للتطبيق، ويُستخدَم لتوليد روابط التطبيق.
  • DB_DATABASE: اسم قاعدة البيانات.
  • DB_USERNAME: اسم المستخدم للاتصال بقاعدة البيانات.
  • DB_PASSWORD: كلمة المرور للاتصال بقاعدة البيانات.

تُضبَط هذه القيم افتراضيًا لبيئة التطوير المحلية التي تستخدم بيئة تطوير Homestead، وهي بيئة أداة Vagrant المُحزَّمة مسبَقًا التي يوفّرها إطار عمل لارافيل، حيث سنغيّر هذه القيم لتمثل إعدادات البيئة الحالية لتطبيقنا.

إذا أردتَ تثبيت لارافيل في بيئة تطوير development أو اختبار testing، فيمكنك ترك الخيار APP_DEBUG مفعّلًا، حيث سيعطيك هذا الخيار معلومات تنقيح الأخطاء المهمة أثناء اختبار التطبيق من المتصفح، ويجب ضبط المتغير APP_ENV على القيمة development أو testing في هذه الحالة. بينما إذا أردتَ تثبيت لارافيل في بيئة الإنتاج، فيجب عليك تعطيل الخيار APP_DEBUG، لأنه يعرض معلومات حساسة حول تطبيقك للمستخدم النهائي، ويجب ضبط المتغير APP_ENV على القيمة production في هذه الحالة.

ملاحظة: يحتوي المتغير APP_KEY على مفتاح فريد ينشأ تلقائيًا عند تثبيت لارافيل باستخدام مدير الحزم Composer، ولست بحاجة إلى تغيير هذه القيمة. إذا أردتَ إنشاء مفتاح أمان جديد، فيمكنك استخدام الأمر php artisan key:generate.

يضبط ملف ‎.env التالي تطبيقنا من أجل عملية التطوير كما يلي:

APP_NAME=TravelList
APP_ENV=development
APP_KEY=APPLICATION_UNIQUE_KEY_DONT_COPY
APP_DEBUG=true
APP_URL=http://domain_or_IP

LOG_CHANNEL=stack

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=travellist
DB_USERNAME=travellist_user
DB_PASSWORD=password

...

عدّل متغيراتك وفقًا لذلك، ثم احفظ الملف وأغلقه للاحتفاظ بالتغييرات التي أجريتها، حيث إذا كنت تستخدم المحرر nano، فيمكنك تطبيق ذلك باستخدام CTRL+X ثم اضغط على Y و Enter للتأكيد.

ضبطنا الآن تطبيق لارافيل، ولكننا ما زلنا بحاجة إلى ضبط خادم الويب حتى نتمكّن من الوصول إليه من المتصفح، حيث سنضبط خادم Nginx لخدمة تطبيق لارافيل في الخطوة التالية.

الخطوة الخامسة: إعداد خادم Nginx

ثبّتنا لارافيل في مجلد محلي من المجلد الرئيسي للمستخدم البعيد، إذ يعمل ذلك جيدًا مع بيئات التطوير المحلية، إلا أنه ليس ممارسة موصًى بها لخوادم الويب المفتوحة لشبكة الإنترنت العامة. سننقل مجلد التطبيق إلى ‎/var/www، وهو الموقع المعتاد لتطبيقات الويب التي تعمل على خادم Nginx.

أولًا، استخدم الأمر mv لنقل مجلد التطبيق بكل محتوياته إلى ‎/var/www/travellist:

sudo mv ~/travellist /var/www/travellist

يجب الآن منح مستخدم خادم الويب إذن الوصول للكتابة في مجلدات storage و cache حيث يخزّن لارافيل الملفات التي أنشأها التطبيق كما يلي:

sudo chown -R www-data.www-data /var/www/travellist/storage
sudo chown -R www-data.www-data /var/www/travellist/bootstrap/cache

أصبحت ملفات التطبيق مرتبة الآن، ولكننا ما زلنا بحاجة إلى ضبط خادم Nginx لخدمة المحتوى، لذا سننشئ ملف ضبط مضيف وهمي جديد في ‎/etc/nginx/sites-available:

sudo nano /etc/nginx/sites-available/travellist

يحتوي ملف الضبط التالي على الإعدادات الموصَى بها لتطبيقات لارافيل على خادم Nginx:

server {
    listen 80;
    server_name server_domain_or_IP;
    root /var/www/travellist/public;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";

    index index.html index.htm index.php;

    charset utf-8;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    error_page 404 /index.php;

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

انسخ هذا المحتوى إلى الملف ‎/etc/nginx/sites-available/travellist، واضبط القيم server_domain_or_IP و travellist التي تمثل اسم الخادم والمجلد الجذر لتتماشى مع ضبطك الخاص إن لزم الأمر. احفظ الملف وأغلقه عند الانتهاء من التعديل.

أنشئ وصلة رمزية إلى travellist في الملف sites-enabled لتنشيط ملف ضبط المضيف الوهمي الجديد كما يلي:

sudo ln -s /etc/nginx/sites-available/travellist /etc/nginx/sites-enabled/

ملاحظة: إذا كان لديك ملف مضيف وهمي آخر مضبوط مسبقًا على اسم الخادم server_name نفسه المُستخدَم في المضيف الوهمي travellist، فيمكن أن تحتاج إلى تعطيل الضبط القديم من خلال إزالة الرابط الرمزي المقابل في /etc/nginx/sites-enabled/.

يمكنك استخدام الأمر التالي للتأكد من أن الضبط لا يحتوي على أيّ أخطاء صياغية:

sudo nginx -t

ويجب أن ترى خرجًا يشبه ما يلي:

Outputnginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

أعِد تحميل خادم Nginx باستخدام الأمر التالي لتطبيق التغييرات:

sudo systemctl reload nginx

انتقل الآن إلى متصفحك وادخل إلى التطبيق باستخدام اسم نطاق أو عنوان IP الخاص بالخادم كما حدّده الموجّه server_name في ملف ضبطك الخاص:

http://server_domain_or_IP

وسترى صفحة تشبه ما يلي:

01_laravel.png

يؤكد ذلك أن خادم Nginx مضبوط بصورة صحيحة لخدمة تطبيق لارافيل، ويمكنك بعد ذلك البدء في إنشاء تطبيقك على التطبيق الهيكلي الذي يوفره التثبيت الافتراضي.

سنعدّل في الخطوة التالية طريق التطبيق الرئيسي للاستعلام عن البيانات في قاعدة البيانات باستخدام واجهة DB في إطار عمل لارافيل.

الخطوة السادسة: إنشاء صفحتك الرئيسية

يجب أن يكون لديك تطبيق لارافيل يعمل بنجاح وجدول قاعدة بيانات بالاسم places يحتوي على بعض البيانات بافتراض أنك اتبعت جميع الخطوات الواردة في هذا المقال حتى الآن، وسنعدّل الآن مسار التطبيق الرئيسي للاستعلام عن قاعدة البيانات وإعادة المحتويات إلى عرض التطبيق.

افتح ملف الموجهات Routes الرئيسي routes/web.php:

nano routes/web.php

يحتوي هذا الملف افتراضيًا على المحتوى التالي:

<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});

تُحدَّد الطرق ضمن هذا الملف باستخدام التابع الساكن Route::get الذي يأخذ مسارًا Path ودالة رد نداء بوصفهما وسائطًا.

تحل الشيفرة البرمجية الآتية محل دالة رد نداء الطريق الرئيسي، حيث تجري استعلامَين إلى قاعدة البيانات باستخدام الراية visited لترشيح النتائج، وتعيد النتائج إلى عرض بالاسم travellist الذي سننشئه لاحقًا. انسخ المحتوى التالي إلى الملف routes/web.php بدلًا من الشيفرة البرمجية الموجودة مسبقًا:

<?php

use Illuminate\Support\Facades\DB;

Route::get('/', function () {
  $visited = DB::select('select * from places where visited = ?', [1]);    
  $togo = DB::select('select * from places where visited = ?', [0]);

  return view('travellist', ['visited' => $visited, 'togo' => $togo ] );
});

احفظ الملف وأغلقه عند الانتهاء من التعديل. سننشئ الآن العرض الذي سيعرض نتائج قاعدة البيانات للمستخدِم، لذا أنشِئ ملف عرض جديد ضمن المجلد resources/views:

nano resources/views/travellist.blade.php

يُنشِئ القالب التالي قائمتين من الأماكن بناءً على المتغيرات visited و togo. انسخ المحتوى التالي إلى ملف العرض الجديد:

<html>
<head>
    <title>Travel List</title>
</head>

<body>
    <h1>My Travel Bucket List</h1>
    <h2>Places I'd Like to Visit</h2>
    <ul>
      @foreach ($togo as $newplace)
        <li>{{ $newplace->name }}</li>
      @endforeach
    </ul>

    <h2>Places I've Already Been To</h2>
    <ul>
          @foreach ($visited as $place)
                <li>{{ $place->name }}</li>
          @endforeach
    </ul>
</body>
</html>

احفظ الملف وأغلقه عند الانتهاء، ثم انتقل إلى متصفحك وأعِد تحميل التطبيق، وسترى الصفحة التالية:

02_travel_list.png

لديك الآن تطبيق لارافيل عملي يسحب المحتويات من قاعدة بيانات MySQL.

الخلاصة

ضبطنا في هذا المقال تطبيق لارافيل جديد باستخدام حزمة LEMP أو (Linux و Nginx و MySQL و PHP) ويعمل على خادم أوبنتو 22.04، وخصّصنا الطريق الافتراضي للاستعلام عن محتوى قاعدة البيانات وعرض النتائج في عرض مُخصَّص.

يمكنك الآن إنشاء طرق وعروض جديدة للصفحات الإضافية التي يحتاجها تطبيقك. اطلع على توثيق لارافيل على موسوعة حسوب لمزيد من المعلومات حول الطرق Routes والعروض Views ودعم قاعدة البيانات، وإذا أردتَ النشر في بيئة الإنتاج، فيمكنك الاطلاع على قسم التحسين Optimization للتعرف على بعض الطرق المختلفة التي يمكنك من خلالها تحسين أداء تطبيقك.

ترجمة -وبتصرُّف- للمقال How To Install and Configure Laravel with Nginx on Ubuntu 20.04 (LEMP) لصاحبته Erika Heidi.

اقرأ أيضًا


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...