SSD Nodes Learn Hosting plans →
الأدلة Matt Connorبقلم Matt Connor · آخر تحديث في 2026-08-07

تثبيت LAMP على Ubuntu 24.04 مع PHP-FPM

ثبّت Apache وMariaDB وPHP 8.3 عبر PHP-FPM على Ubuntu 24.04، واضبط مضيفاً افتراضياً وunix_socket وHTTPS مجانياً عبر Certbot مع حلول الأخطاء الشائعة.

ما الذي ستبنيه

تتكوّن حزمة LAMP من أربعة مكوّنات تعمل على خادم Ubuntu 24.04 واحد: Linux في الطبقة الأساسية، وApache لمعالجة HTTP، وMariaDB لتخزين البيانات، وPHP 8.3 لتشغيل الشيفرة. عند الانتهاء، سيكون لديك مضيف افتراضي يعتمد على اسم النطاق ويخدم دليلاً حقيقياً للتطبيق، وقاعدة بيانات مع مستخدم مخصص بأقل الصلاحيات، وPHP موصولاً بـApache عبر PHP-FPM، وشهادة Let's Encrypt مجانية لحماية الاتصال.

يتطلب التثبيت نفسه أربعة أوامر apt. يتناول معظم هذا الدليل كيفية ربط هذه المكوّنات، إلى جانب مجموعة صغيرة من الأخطاء التي تجعل حزمة جديدة تعرض صفحة فارغة، أو تسلّم الشيفرة المصدرية إلى المتصفح كتنزيل، أو ترفض السماح لك بالدخول إلى قاعدة البيانات التي ثبّتها للتو. لكل خطأ من هذه الأخطاء علامة مميزة يمكنك التعرف إليها، ويُذكر كل منها أدناه مع النص الدقيق الذي ستراه.

المتطلبات الأساسية والمشكلات الفعلية

افترض وجود KVM VPS جديد يعمل بنظام Ubuntu 24.04، مع مستخدم يملك صلاحيات sudo أو حساب root، وعنوان IPv4 عام. تعمل الحزمة الأساسية بذاكرة RAM سعة 1 GB؛ خصص لها 2 GB قبل تثبيت تطبيق فعلي يعتمد على قاعدة بيانات، لأن المخازن المؤقتة الافتراضية في MariaDB، إضافة إلى عدد قليل من عمليات PHP-FPM، تستهلك أول gigabyte بسرعة.

يجب توفر أمرين قبل أن يعمل Certbot في نهاية الإعداد، لذلك جهزهما الآن. تحتاج إلى اسم نطاق يوجّه سجل A الخاص به إلى عنوان IP العام لـVPS. يتحقق Let's Encrypt عبر HTTP من ذلك الاسم، ولا يمكن لعنوان IP مجرد الحصول على شهادة. ويجب أن يكون المنفذان 80 و443 قابلين للوصول من الإنترنت. لدى كثير من مزودي الخدمة، يعني ذلك فتحهما في جدار حماية الشبكة من لوحة التحكم، إضافة إلى ufw على الخادم. قد تستغرق تغييرات DNS مدة تصل إلى ساعة حتى تنتشر، لذلك أنشئ سجل A أولاً، وسيكون فعالاً عند الحاجة إليه.

الخطوة 1 - تثبيت Apache والتحقق من الصفحة الافتراضية

sudo apt update
sudo apt install -y apache2

يبدأ apt الخدمة ويُمكّن تشغيلها عند الإقلاع. تحقّق من ذلك:

systemctl status apache2

ابحث عن سطر يقرأ active (running). افتح الآن http://YOUR_SERVER_IP/ في متصفح. ظهور Apache2 Ubuntu Default Page مع الشريط الكبير "It works!" هو النتيجة الصحيحة. فهذا يثبت أن Apache يقدّم المحتوى، وليس خطأً. توجد هذه الصفحة في /var/www/html/index.html، ويقدّمها المضيف الافتراضي الافتراضي الذي يأتي مع الحزمة، 000-default.conf. ستعطّل كليهما لاحقاً؛ أما الآن، فوجودهما هو بالضبط ما تريد رؤيته.

إذا لم تُحمّل الصفحة إطلاقاً، بينما يشير systemctl إلى أن العملية قيد التشغيل، فهناك جدار ناري يمنع الاتصال. هذه هي الخطوة التالية.

الخطوة 2 - فتح جدار الحماية لـHTTP وHTTPS

تسجّل حزمة apache2 ثلاثة ملفات تعريف لتطبيق ufw. اعرضها:

sudo ufw app list

سترى Apache وApache Full وApache Secure. يخص Apache المنفذ 80 فقط، ويخص Apache Secure المنفذ 443 فقط، بينما يشمل Apache Full المنفذين معاً. وهذا هو الملف الذي تريده، لأنك ستضيف TLS في النهاية.

sudo ufw allow OpenSSH
sudo ufw allow "Apache Full"
sudo ufw enable

اسمح بـOpenSSH قبل تشغيل ufw enable. تكون الإعدادات الافتراضية لـufw هي رفض كل حركة المرور الواردة. وإذا فعّلته من دون قاعدة لـSSH، فسيقطع اتصالك الحالي فور تفعيله، وستبقى الجلسة الحالية مفتوحة، لكنك لن تتمكن من إعادة الاتصال. تحقّق باستخدام sudo ufw status؛ ويجب أن تعرض OpenSSH وApache Full، وكذلك نظيريهما عبر v6، القيمة ALLOW.

الخطوة 3 - تثبيت MariaDB وتأمينه

sudo apt install -y mariadb-server
systemctl status mariadb

يأتي Ubuntu 24.04 مع MariaDB 10.11، وهو إصدار مدعوم على المدى الطويل، لذلك لا تحتاج إلى مستودع خارجي. بعد تشغيل الخدمة، عزّز إعداداتها:

sudo mysql_secure_installation

تستحق المطالبات القراءة بدلاً من الضغط المتكرر على Enter. عندما يطلب كلمة مرور root الحالية، اضغط Enter، إذ لا توجد كلمة مرور بعد. وعندما يسأل "Switch to unix_socket authentication?"، فلا يغيّر الجواب شيئاً لأن هذه المصادقة مفعّلة بالفعل في هذه الحزمة، لذلك اضغط n. أجب n عن السؤال "Change the root password?" للسبب المذكور في الفقرة التالية، ثم أجب Y عن بقية الأسئلة: احذف المستخدمين المجهولين، وامنع تسجيل دخول root عن بُعد، واحذف قاعدة بيانات الاختبار، وأعد تحميل جداول الامتيازات.

إليك الجزء الذي يسبب الالتباس للجميع. في MariaDB على Ubuntu، يستخدم حساب قاعدة البيانات root مصادقة unix_socket، وليس كلمة مرور. هذا يعني أن قاعدة البيانات تثق بمستخدم نظام التشغيل الذي صادقتَ به مسبقاً. لذلك يعمل الأمر التالي من shell الخاص بـroot:

sudo mysql

...وينقلك إلى مطالبة MariaDB [(none)]> من دون طلب كلمة مرور. يُرفض تشغيل الأمر نفسه من مستخدم غير مميّز، وهذه هي الفكرة الأساسية: الوصول إلى root في قاعدة البيانات مرتبط بـsudo على الخادم، ولا توجد كلمة مرور يمكن سرقتها أو استخدامها في التصيد أو تخمينها بالقوة الغاشمة. هذا أكثر أماناً من استخدام كلمة مرور، لذلك اتركه كما هو. والقاعدة الناتجة عن ذلك هي: لا توجّه أي تطبيق إلى حساب root. أنشئ مستخدماً مخصصاً لكل تطبيق (الخطوة 7)، لأن التطبيق الذي يتصل عبر TCP باستخدام اسم مستخدم وكلمة مرور لا يمكنه استخدام مصادقة المقابس، ولأنك تريد تقييد كل تطبيق بقاعدة بياناته الخاصة.

الخطوة 4 - تثبيت PHP 8.3 مع PHP-FPM

الإصدار الافتراضي من PHP في Ubuntu 24.04 هو 8.3. ثبّت مدير عمليات FPM والامتدادات التي تحتاج إليها التطبيقات المعتادة:

sudo apt install -y php8.3-fpm php8.3-mysql php8.3-cli \
  php8.3-curl php8.3-xml php8.3-mbstring php8.3-zip

لاحظ ما لا تتضمنه هذه القائمة: libapache2-mod-php. تدمج هذه الحزمة الأقدم مفسّر PHP داخل كل عملية Apache. هذا الأسلوب بسيط، لكن كل عامل يتضمن نسخة من PHP سواء كان يقدّم برنامجاً نصياً أو صورة ثابتة، كما أن دورة حياة الاثنين مشتركة، ولا يعمل هذا الأسلوب إلا مع MPM من نوع prefork في Apache، وهو الأقل كفاءة. يعمل PHP-FPM بدلاً من ذلك كحوض مستقل من عمليات PHP يتصل به Apache عبر socket. يمكن لـApache عندئذ استخدام MPM من نوع event للملفات الثابتة وتمرير طلبات PHP فقط إلى الحوض. ويمكن ضبط الحوض بشكل مستقل عن خادم الويب، كما يعمل إعداد FPM نفسه لاحقاً إذا وضعت nginx أمامه. وهذا هو الإعداد الافتراضي الحالي لسبب وجيه.

يتصل Apache بـFPM عبر الوحدة proxy_fcgi. فعّلها، وفعّل الإعداد الذي أضافته حزمة FPM، ثم أعد التشغيل:

sudo a2enmod proxy_fcgi setenvif
sudo a2enconf php8.3-fpm
sudo systemctl restart apache2

يؤدي a2enconf php8.3-fpm إلى تفعيل /etc/apache2/conf-available/php8.3-fpm.conf، الذي يتضمن القاعدة التي توجّه ملفات PHP إلى FPM socket. يطابق هذا الإعداد أي ملف .php ويمرّره إلى socket الموجود في /run/php/php8.3-fpm.sock:

<FilesMatch ".+\.ph(ar|p|tml)$">
    SetHandler "proxy:unix:/run/php/php8.3-fpm.sock|fcgi://localhost"
</FilesMatch>

لا تعدّل هذا الملف؛ فهو يأتي مضبوطاً بشكل صحيح. لكن معرفة مسار socket تتيح لك تشخيص مشكلتي «تنزيل PHP بدلاً من تشغيله» و«البرنامج النصي الأساسي غير معروف» لاحقاً. وكلتاهما تنتجان عن اختلاف Apache وFPM بشأن هذا socket أو الملف الموجود خلفه.

الخطوة 5 - مضيف افتراضي يعتمد على الاسم لتطبيقك

تتيح الاستضافة الافتراضية المعتمدة على الاسم لعنوان IP واحد خدمة عدة مواقع؛ إذ يختار Apache الموقع بناءً على ترويسة Host: في الطلب. أنشئ دليلاً للتطبيق، بعيداً عن /var/www/html الافتراضي:

sudo mkdir -p /var/www/testapp
sudo chown -R www-data:www-data /var/www/testapp
sudo chmod -R 755 /var/www/testapp

تُعد الملكية مهمة. يعمل كل من Apache وPHP-FPM بحساب المستخدم www-data على Ubuntu، لذلك يجب أن تكون ملكية الملفات التي يحتاج خادم الويب إلى قراءتها، والأدلة التي يحتاج التطبيق إلى الكتابة فيها مثل دليل uploads، للمستخدم www-data. إذا كنت ستعدّل الملفات أيضاً بحساب تسجيل الدخول الخاص بك، فالنمط الشائع هو أن تكون ملكية الملفات لك وأن تضيف مستخدمك إلى المجموعة www-data؛ أما في عملية نشر بسيطة، فإن www-data:www-data هو الخيار الأقل تسبباً بالمفاجآت.

أنشئ المضيف الافتراضي في /etc/apache2/sites-available/testapp.conf:

<VirtualHost *:80>
    ServerName app.example.com
    DocumentRoot /var/www/testapp

    <Directory /var/www/testapp>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/testapp-error.log
    CustomLog ${APACHE_LOG_DIR}/testapp-access.log combined
</VirtualHost>

اضبط ServerName على نطاقك الحقيقي. يمنع Options -Indexes Apache من عرض محتويات الدليل عند عدم وجود ملف فهرس؛ وإلا فسيتمكن الزوار من تصفح شجرة المصدر لديك. يتيح AllowOverride All تشغيل ملف .htaccess، وهو ما تتوقعه معظم تطبيقات PHP لعناوين URL الواضحة؛ عطّله بالقيمة None لتحسين بسيط في السرعة إذا لم يكن تطبيقك يحتاج إليه. فعّل هذا الموقع، عطّل الموقع الافتراضي، وتحقق من الإعدادات ثم أعد التحميل:

sudo a2ensite testapp
sudo a2dissite 000-default
sudo apache2ctl configtest
sudo systemctl reload apache2

يجب أن يطبع apache2ctl configtest القيمة Syntax OK. سطر a2dissite 000-default هو ما ينساه الناس عادةً، ولذلك تظهر الصفحة الافتراضية لاحقاً وكأنها عالقة، كما هو موضح في قسم حالات الفشل.

الخطوة 6 - أثبت أن PHP يعمل، ثم احذف ملف الإثبات

ضع ملف PHP من سطر واحد في جذر التطبيق:

echo "<?php phpinfo();" | sudo tee /var/www/testapp/info.php

افتح http://app.example.com/info.php. النتيجة الصحيحة هي جدول PHP Version 8.3.x الطويل باللونين البنفسجي والرمادي، ويعرض الوحدات المحمّلة، مع ظهور السطر Server API بالقيمة FPM/FastCGI. يؤكد هذا السطر الأخير أن الطلبات تمر عبر PHP-FPM، وليس mod_php.

احذفه فوراً:

sudo rm /var/www/testapp/info.php

يكشف phpinfo() إصدار PHP الدقيق، وكل امتداد محمّل، ومسارات الملفات، وتفاصيل البيئة. وهذا يوفر معلومات لمن يفحص الخادم بحثاً عن إصدار يتضمن ثغرة معروفة. هذا اختبار وليس ميزة. احذفه بمجرد رؤية الصفحة. إذا عرض المتصفح تنزيل info.php بدلاً من عرض الجدول، فهذا يعني أن PHP غير موصول بـApache؛ انتقل إلى قسم حالات الفشل قبل تنفيذ أي إجراء آخر.

الخطوة 7 - إنشاء قاعدة بيانات التطبيق ومستخدم بأقل قدر من الامتيازات

افتح قاعدة البيانات باستخدام root الذي تتم مصادقته عبر المقبس:

sudo mysql

أنشئ بعد ذلك قاعدة بيانات واحدة ومستخدماً واحداً يقتصر نطاقه على قاعدة البيانات تلك تحديداً:

CREATE DATABASE appdb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'appuser'@'localhost' IDENTIFIED BY 'a-long-random-password';
GRANT ALL PRIVILEGES ON appdb.* TO 'appuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;

هناك 3 اختيارات مقصودة هنا. utf8mb4 هو UTF-8 حقيقي بأربعة بايتات، أما الاسم المستعار القديم utf8 فيقتطع رموز emoji وبعض أحرف CJK بصمت، لذلك استخدم دائماً utf8mb4. المنح موجّه إلى appdb.*، وليس إلى *.*: يستطيع هذا المستخدم الوصول إلى قاعدة بياناته فقط، ولا شيء غيرها، لذلك لا يمكن لثغرة SQL injection في التطبيق قراءة جداول جميع المواقع الأخرى. ويقيّد 'appuser'@'localhost' الحساب بالاتصالات الصادرة من الخادم نفسه.

اختبر الاتصال باستخدام هذا المستخدم:

mysql -u appuser -p appdb

سيطلب الأمر كلمة المرور، ثم يفتح لك موجه MariaDB [appdb]>. لاحظ عدم وجود الخيار -h. اتركه محذوفاً، وسيتصل العميل عبر Unix socket المحلي، وهذا تحديداً ما تعدّه MariaDB قيمة localhost. هناك نقطة مهمة: بالنسبة إلى MySQL وMariaDB، localhost يعني Unix socket، بينما 127.0.0.1 يعني اتصال TCP. في MariaDB على Ubuntu 24.04 بالإعدادات الافتراضية، يحل الخادم اتصال TCP من 127.0.0.1 مرة أخرى إلى localhost، لذلك يتطابق كلاهما مع الحساب. لكن عند تفعيل skip-name-resolve على الخوادم، وهو تحسين شائع للأداء والإعداد المعتاد في كثير من صور الحاويات، تتم مطابقة الاثنين كمضيفين مختلفين. عندها يُرفض التطبيق الذي يتصل عبر 127.0.0.1 برسالة ERROR 1045 (28000): Access denied for user 'appuser'@'127.0.0.1' (using password: YES) حتى عندما تكون كلمة المرور صحيحة.

وجّه تطبيقك إلى المضيف localhost، والمستخدم appuser، وقاعدة البيانات appdb، ولا تستخدم root. ينتقل كل من mysqli في PHP وPDO إلى Unix socket عندما يكون المضيف هو السلسلة الحرفية localhost، وبذلك يطابقان الحساب الذي أنشأته للتو. إذا أصر إطار العمل على استخدام مضيف TCP رقمي، فأنشئ المستخدم بما يطابق طريقة اتصاله الفعلية، أي 'appuser'@'127.0.0.1'، أو @'%' مع قاعدة جدار ناري، ولكن فقط إذا كان يجب أن يصل إلى قاعدة البيانات من جهاز آخر.

الخطوة 8 - إضافة HTTPS باستخدام Certbot

يؤدي تقديم نموذج تسجيل الدخول عبر HTTP العادي إلى إرسال كلمات المرور بنص واضح، وتضع كل متصفحات الويب الحديثة علامة "غير آمن" على الصفحة. يحل Certbot هذه المشكلة باستخدام أمر واحد. ثبّته مع إضافة Apache:

sudo apt install -y certbot python3-certbot-apache
sudo certbot --apache

يستخدم Certbot هنا إضافتين. يثبت موثّق Apache أنك تتحكم في النطاق من خلال تقديم ملف challenge مؤقتاً عبر Apache العامل لديك. ثم يعيد مثبّت Apache كتابة المضيف الافتراضي لإضافة كتلة 443، ويوجّهها إلى الشهادة الجديدة، ويعيد توجيه كل حركة مرور HTTP إلى HTTPS افتراضياً. منذ Certbot 2.0، لا يظهر سؤال إعادة التوجيه. مرّر --no-redirect إذا كنت تحتاج إلى مواصلة تقديم HTTP العادي. لأنك عيّنت ServerName حقيقياً في الخطوة 5، يكتشف Certbot النطاق تلقائياً. تستمر الشهادات 90 يوماً، وتثبّت الحزمة مؤقت systemd لتجديدها. تحقّق من المؤقت باستخدام sudo certbot renew --dry-run، وينبغي أن تنتهي النتيجة بـ Congratulations, all simulated renewals succeeded.

للاطلاع على الشرح الكامل للتحدي، ومؤقت التجديد، ومتطلبات DNS والجدار الناري، راجع الدليل المرافق حول إصدار شهادات TLS مجانية من Let's Encrypt باستخدام Certbot على Apache.

النسخ الاحتياطية والترقيات والتقوية

أنشئ نسخاً احتياطية من العنصرين اللذين يحتفظان بحالتك: قواعد البيانات وجذر الويب. يُعد التفريغ المنطقي الليلي أبسط نهج موثوق، sudo sh -c 'mysqldump --all-databases --single-transaction | gzip > /root/db-$(date +%F).sql.gz'، ثم انسخه إلى خارج الخادم. من المهم وضع خط الأنابيب بأكمله داخل sudo sh -c: من دونه، تنفّذ الصدفة إعادة التوجيه > /root/... بصلاحيات مستخدمك، وتفشل بسبب Permission denied، لأن mysqldump وحده ورث sudo. يوفّر --single-transaction لقطة متسقة لجداول InnoDB من دون قفلها. اقرنه بـtar لـ/var/www و/etc/apache2/sites-available، ويمكنك إعادة بناء الحزمة بأكملها على VPS جديد من هذه الملفات.

الترقيات عبارة عن sudo apt update && sudo apt upgrade اعتيادي. المشكلة التي تسبب الأعطال هي ترقية إصدار PHP. عندما تنقل نسخة مستقبلية من Ubuntu الإصدار الافتراضي إلى PHP 8.4، قد يثبّت apt الإصدار php8.4-fpm إلى جانب 8.3، ويصبح المقبس /run/php/php8.4-fpm.sock، بينما يظل إعداد Apache يشير إلى مقبس 8.3. فعّل ملف الإعداد الجديد (sudo a2enconf php8.4-fpm) وعطّل القديم، وإلا سيبدأ موقعك بإرجاع Primary script unknown بعد ترقية اعتيادية لم تسبب مشكلات أخرى. لأن إصدارات PHP تتغير بوتيرة أسرع من توزيعة LTS، راجع ملاحظات إصدار PHP الحالية بدلاً من تثبيت إصدار تصحيحي محدد.

هناك خطوتان للتقوية يجدر تنفيذُهما في اليوم الأول. أولاً، ثبّت Fail2Ban لمراقبة SSH على الخادم. يتلقى VPS العام محاولات تسجيل دخول آلية خلال دقائق، ويحوّل jail صغير آلاف المحاولات إلى عدد قليل منها قبل الحظر. ثانياً، إذا كنت تفضّل إدارة مضيفات Apache الافتراضية وقواعد بيانات MariaDB والمستخدمين عبر المتصفح بدلاً من تعديل الملفات يدوياً، فإن لوحة Webmin للتحكم المعتمدة على الويب تعمل فوق هذه الحزمة نفسها وتدير ملفات الإعداد التي كتبتها للتو. لا يحل أي منهما محل فهم المكونات، لكن كليهما يقلل الاحتكاك في العمل اليومي.

أنماط الفشل، مع النصوص التي ستظهر لك

لا تختفي الصفحة الافتراضية. عدّلت المضيف الافتراضي وأعدت التحميل، لكن المتصفح ما زال يعرض "Apache2 Ubuntu Default Page" وشريط "It works!". يقدّم Apache أول مضيف افتراضي مطابق، وعندما لا يطابق أي ServerName الطلب، يفوز ملف الإعداد الأول أبجدياً؛ إذ يأتي 000-default.conf قبل testapp.conf في الترتيب. إما أن اسم المضيف في الطلب لا يطابق ServerName، أو أنك لم تشغّل sudo a2dissite 000-default. عطّل الإعداد الافتراضي باستخدام sudo systemctl reload apache2، وتحقق باستخدام apache2ctl -S، الذي يطبع خريطة المضيفين الافتراضيين ويوضح أي إعداد يملك المضيف الافتراضي. امسح ذاكرة التخزين المؤقت للمتصفح أيضاً؛ فقد تبقى استجابة 200 المخزنة من الصفحة القديمة ظاهرة.

يُنزَّل ملف .php بدلاً من تشغيله. تفتح info.php، فينزّل المتصفح ملفاً يحتوي على المصدر الخام لـ<?php، أو يعرضه كنص عادي، بدلاً من تشغيله. يقدّم Apache الملف كأصل ثابت لأن معالج PHP غير مرتبط به، أو لأنك تخطيت sudo a2enmod proxy_fcgi أو sudo a2enconf php8.3-fpm، أو لم تُعد تشغيل Apache بعد ذلك. شغّل الأوامر الثلاثة كلها (الخطوة 4) ثم أعد التحميل. تحقق من تحميل الوحدة باستخدام apache2ctl -M | grep fcgi، الذي يجب أن يعرض proxy_fcgi_module. هذا تسرّب لشفرة المصدر، وليس مشكلة شكلية، لذلك أصلحه قبل وضع أي شيء فعلي على الخادم.

ERROR 1698 (28000): Access denied for user 'root'@'localhost'. شغّلت mysql -u root أو mariadb -u root من دون sudo. يستخدم حساب root المصادقة عبر unix_socket، لذلك لا يقبلك إلا عندما يكون مستخدم نظام التشغيل لديك هو root فعلياً. الحل هو sudo mysql، من دون -u root ومن دون كلمة مرور. هذه الرسالة هي السلوك المتوقع للمصادقة عبر socket عندما تعمل بشكل صحيح، وليست دليلاً على تلف التثبيت.

ERROR 1045 (28000): Access denied for user 'appuser'@'127.0.0.1' من التطبيق، رغم استخدام كلمة المرور الصحيحة. الحساب موجود باسم 'appuser'@'localhost'، لكن تطبيقك يتصل عبر TCP بالمضيف 127.0.0.1 على خادم عطّل حل أسماء المضيفين (skip-name-resolve)، لذلك يتعامل MariaDB معهما كمضيفين مختلفين؛ localhost هو Unix socket، و127.0.0.1 هو TCP. وجّه التطبيق إلى المضيف localhost كي يستخدم socket ويطابق الحساب، أو أنشئ حساباً ثانياً باسم 'appuser'@'127.0.0.1' إذا كان إطار العمل لا يتحدث إلا عبر TCP.

AH01071: Got error 'Primary script unknown' في /var/log/apache2/testapp-error.log، بينما يعرض المتصفح File not found.. سلّم Apache الطلب إلى PHP-FPM، لكن FPM لم يتمكن من العثور على البرنامج النصي في المسار الذي أعطاه Apache له. السببان المعتادان هما: أن socket الخاص بـFPM في إعدادك يشير إلى إصدار PHP غير مثبت، مثل socket بإصدار php8.4 بعد الترقية بينما يعمل الإصدار 8.3 فقط؛ أو أن الملف غير موجود فعلياً لأن DocumentRoot والمجلد الفعلي غير متطابقين. تحقق من وجود socket باستخدام ls -l /run/php/، وتأكد من أن DocumentRoot يطابق مكان وجود الملف، ثم أعد تشغيل كل من php8.3-fpm وapache2.

AH00558: apache2: Could not reliably determine the server's fully qualified domain name عند كل إعادة تشغيل. هذا تحذير غير ضار، وليس خطأ. يخبرك Apache بعدم ضبط ServerName عام. أوقف ظهوره بكتابة ServerName your.domain داخل /etc/apache2/conf-available/servername.conf، ثم شغّل sudo a2enconf servername.

(98)Address already in use: AH00072: make_sock: could not bind to address 0.0.0.0:80 عند بدء Apache. يشغل خادم ويب آخر المنفذ 80 مسبقاً، وغالباً يكون nginx متروكاً من تجربة سابقة. اعثر عليه باستخدام sudo ss -ltnp | grep :80، ثم أوقف الخدمة الأخرى وعطّلها قبل بدء Apache.

FAQ

mod_php أم PHP-FPM — أيهما أستخدم؟

استخدم PHP-FPM. يضمّن mod_php مفسّراً في كل عملية Apache ويفرض استخدام MPM البطيء prefork، لذلك يحمّل Apache عبء PHP حتى عند تقديم صورة ثابتة. يشغّل PHP-FPM PHP ضمن pool منفصل يمكن ضبطه باستقلالية، ويتصل به Apache عبر socket، ويعمل مع MPM event الأسرع ذي الخيوط، كما يمكن نقله لاحقاً دون تغيير إلى nginx. وهو الخيار الافتراضي الحديث؛ ولا يكون mod_php مناسباً إلا لتطبيق قديم يعتمد على سلوك معين داخل العملية.

لماذا ينزّل المتصفح ملف PHP بدلاً من تشغيله؟

يتعامل Apache مع ملف .php كتنزيل ثابت لأن PHP handler غير مرتبط به. في Ubuntu 24.04 مع FPM، يعني ذلك أنك لم تنفّذ واحداً من sudo a2enmod proxy_fcgi أو sudo a2enconf php8.3-fpm أو لم تعِد تشغيل Apache بعد ذلك. نفّذ الأوامر الثلاثة ثم أعد التحميل، وتحقق باستخدام apache2ctl -M | grep fcgi من ظهور proxy_fcgi_module في القائمة. إلى أن تصلح المشكلة، يسرّب الخادم الشفرة المصدرية؛ لذلك تعامل معها باعتبارها عاجلة.

لماذا يُرفض وصول root في MariaDB رغم استخدام كلمة المرور الصحيحة؟

لأنه لا توجد كلمة مرور. تصادق MariaDB في Ubuntu على حساب root باستخدام unix_socket، ما يربطه بمستخدم root في نظام التشغيل. يعيد mysql -u root من shell عادي القيمة ERROR 1698 (28000): Access denied for user 'root'@'localhost' عن قصد. اتصل باستخدام sudo mysql بدلاً من ذلك، وأنشئ مستخدماً منفصلاً موثَّقاً بكلمة مرور لكل تطبيق، ولا تعِد استخدام root.

كيف أضيف HTTPS إلى موقعي الذي يعمل على LAMP؟

ثبّت certbot وpython3-certbot-apache، ووجّه سجل A للنطاق إلى الخادم، ثم شغّل sudo certbot --apache. يثبت apache authenticator أنك تتحكم في النطاق من خلال Apache الذي يعمل لديك، ويعدّل المثبّت إعدادات virtual host للمنفذ 443 ويضبط التجديد التلقائي. يشرح الدليل الكامل لإعداد Certbot وApache التحدي، ومؤقت التجديد، وأوضاع الفشل الشائعة.

#lamp#apache#mariadb#php-fpm#ubuntu