SSD Nodes Learn Hosting plans →
تعلیمی Matt Connorتحریر: Matt Connor · اپ ڈیٹ شدہ 2026-08-07

Ubuntu 24.04 پر LAMP stack اور PHP-FPM کی تنصیب

Ubuntu 24.04 پر Apache، MariaDB unix_socket auth، PHP 8.3 اور PHP-FPM کے ساتھ LAMP stack بنائیں، name-based vhost قائم کریں اور Certbot سے مفت HTTPS فعال کریں۔

آپ کیا بنا رہے ہیں

LAMP stack ایک ہی Ubuntu 24.04 server پر چلنے والے چار اجزا پر مشتمل ہے: نیچے Linux، HTTP درخواستوں کے جواب دینے والا Apache، data محفوظ رکھنے والا MariaDB، اور code چلانے والا PHP 8.3۔ آخر تک آپ کے پاس ایک name-based virtual host ہوگا جو application کی حقیقی directory فراہم کرے گا، کم سے کم مراعات والے dedicated user کے ساتھ database ہوگا، PHP-FPM کے ذریعے Apache کے ساتھ مربوط PHP ہوگا، اور اس کے اوپر مفت Let's Encrypt certificate ہوگا۔

تنصیب خود چار apt commands پر مشتمل ہے۔ اس guide کا تقریباً تمام حصہ ان اجزا کو آپس میں مربوط کرنے اور ان چند غلطیوں سے نمٹنے کے بارے میں ہے جن کی وجہ سے نیا stack blank page فراہم کرتا ہے، source code کو download کے طور پر browser کے حوالے کرتا ہے، یا آپ کو ابھی نصب کیے گئے database میں داخل نہیں ہونے دیتا۔ ان میں سے ہر صورت کی ایک قابل شناخت علامت ہوتی ہے، اور ذیل میں ہر ایک کے ساتھ وہ عین متن بھی دیا گیا ہے جو آپ دیکھیں گے۔

ضروریات اور اہم عملی نکات

فرض کریں کہ آپ کے پاس نیا Ubuntu 24.04 KVM VPS ہے، جس پر sudo صارف یا root دستیاب ہے، اور ایک public IPv4 address موجود ہے۔ کم سے کم stack 1 GB RAM میں چل جاتا ہے، لیکن حقیقی database-backed application نصب کرنے سے پہلے اسے 2 GB RAM دیں، کیونکہ MariaDB کے default buffers اور چند PHP-FPM workers مل کر پہلا gigabyte جلد استعمال کر لیتے ہیں۔

Certbot کے آخر میں کام کرنے سے پہلے دو باتیں درست ہونی چاہئیں، اس لیے انہیں ابھی ترتیب دے دیں۔ آپ کے پاس ایک domain name ہونا چاہیے جس کا A record VPS کے public IP کی طرف اشارہ کرے۔ Let's Encrypt اسی نام پر HTTP کے ذریعے توثیق کرتا ہے، اور صرف IP address کے لیے کبھی certificate جاری نہیں کیا جا سکتا۔ اس کے علاوہ ports 80 and 443 انٹرنیٹ سے قابل رسائی ہونے چاہئیں۔ بہت سے providers میں اس کے لیے control panel کے network firewall میں انہیں کھولنے کے ساتھ ساتھ مشین پر موجود ufw میں بھی اجازت دینا ضروری ہوتا ہے۔ DNS تبدیلیوں کو propagate ہونے میں ایک گھنٹے تک لگ سکتا ہے، اس لیے A record پہلے بنا دیں تاکہ ضرورت کے وقت یہ فعال ہو۔

مرحلہ 1 - Apache انسٹال کریں اور default page کی تصدیق کریں

sudo apt update
sudo apt install -y apache2

apt آپ کے لیے service شروع اور enable کرتا ہے۔ اس کی جانچ کریں:

systemctl status apache2

آپ کو active (running) پر مشتمل ایک سطر نظر آنی چاہیے۔ اب browser میں http://YOUR_SERVER_IP/ کھولیں۔ بڑے "It works!" banner والا Apache2 Ubuntu Default Page درست نتیجہ ہے۔ یہ اس بات کا ثبوت ہے کہ Apache درخواستیں serve کر رہا ہے، کوئی خرابی نہیں۔ یہ صفحہ /var/www/html/index.html پر موجود ہے اور shipped default virtual host 000-default.conf کے ذریعے serve ہوتا ہے۔ آپ بعد میں دونوں کو disable کریں گے؛ فی الحال ان کا موجود ہونا بالکل وہی ہے جو آپ دیکھنا چاہتے ہیں۔

اگر صفحہ بالکل load نہ ہو، لیکن systemctl بتائے کہ process چل رہا ہے، تو firewall رکاوٹ بن رہا ہے۔ یہی اگلا مرحلہ ہے۔

مرحلہ 2 - HTTP اور HTTPS کے لیے firewall کھولیں

apache2 پیکیج تین ufw application profiles رجسٹر کرتا ہے۔ انہیں فہرست میں دکھائیں:

sudo ufw app list

آپ کو Apache، Apache Full، اور Apache Secure نظر آئیں گے۔ Apache صرف port 80 کے لیے ہے، Apache Secure صرف port 443 کے لیے ہے، اور Apache Full دونوں کے لیے ہے۔ آپ کو یہی profile چاہیے، کیونکہ آخر میں TLS شامل کیا جائے گا۔

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

ufw enable چلانے سے پہلے OpenSSH کی اجازت دیں۔ ufw کی default configuration تمام incoming traffic کو deny کرتی ہے۔ اگر SSH rule کے بغیر اسے فعال کیا جائے تو اس کے فعال ہوتے ہی آپ کا موجودہ connection برقرار رہتا ہے، لیکن آپ دوبارہ connect نہیں کر سکیں گے۔ sudo ufw status سے تصدیق کریں؛ OpenSSH، Apache Full، اور ان کے v6 equivalents سب کے سامنے ALLOW درج ہونا چاہیے۔

مرحلہ 3 - MariaDB انسٹال کریں اور اسے محفوظ بنائیں

sudo apt install -y mariadb-server
systemctl status mariadb

Ubuntu 24.04 کے ساتھ MariaDB 10.11 فراہم ہوتا ہے، جو long-term-support release ہے، اس لیے آپ کو external repository کی ضرورت نہیں۔ service چلنے کے بعد اسے harden کریں:

sudo mysql_secure_installation

Prompts کو Enter دباتے ہوئے نظرانداز کرنے کے بجائے غور سے پڑھیں۔ جب current root password پوچھا جائے تو Enter دبائیں، کیونکہ ابھی کوئی password موجود نہیں۔ جب "Switch to unix_socket authentication?" پوچھا جائے تو جواب سے کچھ تبدیل نہیں ہوگا، کیونکہ اس package میں یہ پہلے ہی enabled ہے؛ اس لیے n دبائیں۔ اگلے paragraph میں بیان کی گئی وجہ سے "Change the root password?" کے جواب میں n دیں، پھر باقی سوالات کے جواب میں Y دیں: anonymous users کو remove کریں، remote root login کو disallow کریں، test database کو drop کریں، اور privilege tables کو reload کریں۔

یہ وہ حصہ ہے جو سب کو الجھن میں ڈالتا ہے۔ Ubuntu کی MariaDB میں root database account password کے بجائے unix_socket authentication استعمال کرتا ہے۔ اس کا مطلب ہے کہ database اس operating-system user پر اعتماد کرتا ہے جس کے طور پر آپ پہلے ہی authenticated ہیں۔ اس لیے root shell سے یہ command کام کرتی ہے:

sudo mysql

...اور آپ کو MariaDB [(none)]> prompt دکھائی دیتا ہے، جس میں password نہیں مانگا جاتا۔ یہی command کسی unprivileged user کے طور پر چلانے پر مسترد ہو جاتی ہے، اور یہی اصل مقصد ہے: database root تک access مشین پر موجود sudo سے منسلک ہے، اور چوری، phishing یا brute-force کے لیے کوئی password موجود نہیں۔ یہ password سے زیادہ محفوظ ہے، اس لیے اسے تبدیل نہ کریں۔ اس سے یہ اصول نکلتا ہے: کبھی بھی کسی application کو root account کے ذریعے connect نہ کریں۔ ہر application کے لیے dedicated user بنائیں (مرحلہ 7)، کیونکہ TCP کے ذریعے username اور password کے ساتھ connect کرنے والی app socket authentication استعمال نہیں کر سکتی، اور آپ چاہتے ہیں کہ ہر app صرف اپنی database تک محدود رہے۔

مرحلہ 4 - PHP 8.3 کو PHP-FPM کے ساتھ انسٹال کریں

Ubuntu 24.04 کا default PHP ورژن 8.3 ہے۔ FPM process manager اور عام ایپ کے لیے درکار extensions انسٹال کریں:

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۔ یہ پرانا package ہر Apache process کے اندر PHP interpreter شامل کرتا ہے۔ یہ سادہ طریقہ ہے، لیکن ہر worker میں PHP کی ایک copy موجود رہتی ہے، چاہے وہ script فراہم کر رہا ہو یا static image۔ دونوں کا lifecycle بھی مشترک ہوتا ہے، اور یہ صرف Apache کے prefork MPM کے ساتھ کام کرتا ہے، جو سب سے کم مؤثر MPM ہے۔ اس کے برعکس PHP-FPM PHP کو اپنے الگ process pool کے طور پر چلاتا ہے، جس سے Apache socket کے ذریعے رابطہ کرتا ہے۔ اس طرح Apache static files کے لیے threaded event MPM استعمال کر سکتا ہے اور صرف PHP requests آگے بھیجتا ہے۔ Process pool کو web server سے آزادانہ طور پر tune کیا جا سکتا ہے، اور بعد میں اگر آپ nginx کو سامنے رکھیں تو یہی FPM setup کام کرتا ہے۔ یہ موجودہ default ہونے کی معقول وجہ ہے۔

Apache، proxy_fcgi module کے ذریعے FPM تک پہنچتا ہے۔ اسے enable کریں، FPM package کی جانب سے شامل کی گئی config کو enable کریں، پھر restart کریں:

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 کو activate کرتا ہے۔ اس میں وہ rule شامل ہے جو PHP files کو FPM socket تک route کرتا ہے۔ اس rule کا مرکزی حصہ ہر .php file سے match کرتا ہے اور اسے /run/php/php8.3-fpm.sock پر موجود socket تک forward کرتا ہے:

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

اس file میں ترمیم نہ کریں؛ یہ درست configuration کے ساتھ package کا حصہ ہوتی ہے۔ تاہم socket path معلوم ہونا بعد میں آنے والی "PHP downloads instead of running" اور "Primary script unknown" failures کی تشخیص کے لیے ضروری ہے۔ دونوں failures کی بنیادی وجہ یہ ہوتی ہے کہ Apache اور FPM اس socket یا اس کے پیچھے موجود file کے بارے میں متفق نہیں ہوتے۔

مرحلہ 5 - اپنی ایپ کے لیے نام پر مبنی virtual host

نام پر مبنی virtual hosting کے ذریعے ایک IP متعدد sites فراہم کر سکتا ہے؛ Apache درخواست میں موجود Host: header کی بنیاد پر site منتخب کرتا ہے۔ ایپ کے لیے ایک directory بنائیں، اور اسے default /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

Ownership اہم ہے۔ Ubuntu پر Apache اور PHP-FPM دونوں www-data user کے طور پر چلتے ہیں، اس لیے web server کو جن files کو پڑھنا ہو، اور app کو جن directories میں لکھنا ہو، مثلاً uploads folder، ان کا owner www-data ہونا چاہیے۔ اگر آپ اپنے login user کے طور پر files میں ترمیم بھی کریں گے تو عام طریقہ یہ ہے کہ files کا owner آپ خود ہوں اور اپنے user کو www-data group میں شامل کریں؛ سادہ deploy کے لیے www-data:www-data سب سے کم باعثِ الجھن انتخاب ہے۔

Virtual host کو /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 کو اپنے حقیقی domain پر set کریں۔ Options -Indexes Apache کو اس وقت directory listing دکھانے سے روکتا ہے جب index file موجود نہ ہو؛ بصورتِ دیگر visitors آپ کا source tree browse کر سکتے ہیں۔ AllowOverride All کے ذریعے .htaccess file کام کرتی ہے، جس کی زیادہ تر PHP applications کو pretty URLs کے لیے توقع ہوتی ہے؛ اگر آپ کی app کو اس کی ضرورت نہ ہو تو معمولی speed gain کے لیے اسے None کر دیں۔ اس site کو enable کریں، default کو disable کریں، configuration check کریں، اور reload کریں:

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

apache2ctl configtest کو Syntax OK print کرنا چاہیے۔ a2dissite 000-default line وہ ہے جسے لوگ اکثر بھول جاتے ہیں، اور اسی وجہ سے بعد میں default page ایسے ظاہر ہوتا ہے جیسے وہ stuck ہو؛ اس کی وضاحت failures section میں کی گئی ہے۔

مرحلہ 6 - ثابت کریں کہ PHP چل رہا ہے، پھر ثبوت حذف کریں

ایپ کی root directory میں PHP کی ایک سطری فائل رکھیں:

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

http://app.example.com/info.php ملاحظہ کریں۔ درست نتیجہ ایک طویل ارغوانی اور سرمئی PHP Version 8.3.x جدول ہے، جس میں لوڈ کیے گئے modules درج ہوتے ہیں اور Server API والی سطر میں FPM/FastCGI لکھا ہوتا ہے۔ آخری سطر اس بات کی تصدیق کرتی ہے کہ requests PHP-FPM کے ذریعے جا رہی ہیں، mod_php کے ذریعے نہیں۔

اب اسے فوراً حذف کریں:

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

phpinfo() آپ کا درست PHP version، تمام loaded extensions، file paths اور environment کی تفصیلات ظاہر کرتا ہے۔ یہ اس شخص کے لیے مفید معلومات ہیں جو معلوم vulnerability والے version کے لیے server کو probe کر رہا ہو۔ یہ صرف test ہے، feature نہیں۔ صفحہ دیکھتے ہی اسے حذف کر دیں۔ اگر جدول کے بجائے browser نے info.php کو download کرنے کی پیشکش کی، تو PHP Apache کے ساتھ wired نہیں ہے؛ کوئی اور کام کرنے سے پہلے failures section پر جائیں۔

مرحلہ 7 - ایپلیکیشن کا database بنائیں اور کم سے کم مراعات والا user بنائیں

socket authentication کے ذریعے root کے طور پر database کھولیں:

sudo mysql

پھر صرف اسی database تک محدود ایک database اور ایک user بنائیں:

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;

یہاں تین سوچے سمجھے فیصلے کیے گئے ہیں۔ utf8mb4 حقیقی چار-byte UTF-8 ہے، جبکہ پرانا utf8 alias emoji اور بعض CJK characters کو خاموشی سے truncate کر دیتا ہے، اس لیے ہمیشہ utf8mb4 استعمال کریں۔ grant appdb.* پر ہے، *.* پر نہیں: یہ user صرف اپنے database تک رسائی رکھتا ہے، اس لیے ایپلیکیشن میں SQL injection کی خامی ہونے پر بھی یہ دوسری sites کے تمام tables نہیں پڑھ سکتا۔ اور 'appuser'@'localhost' اس account کو صرف اسی machine سے آنے والی connections تک محدود کرتا ہے۔

اس user کے طور پر test کریں:

mysql -u appuser -p appdb

یہ password مانگتا ہے اور آپ کو MariaDB [appdb]> prompt پر لے آتا ہے۔ غور کریں کہ -h flag موجود نہیں ہے۔ اسے شامل نہ کریں؛ اس صورت میں client مقامی Unix socket کے ذریعے connect ہوتا ہے، اور MariaDB اسی کو localhost شمار کرتا ہے۔ ایک اہم نکتہ یہ ہے: MySQL اور MariaDB میں localhost سے مراد Unix socket ہے اور 127.0.0.1 سے مراد TCP connection ہے۔ عام Ubuntu 24.04 MariaDB پر server اب بھی 127.0.0.1 سے آنے والی TCP connection کو localhost میں resolve کرتا ہے، اس لیے دونوں account سے match ہو جاتے ہیں۔ لیکن جن servers پر skip-name-resolve enabled ہو، جو performance بہتر بنانے کی ایک عام تبدیلی ہے اور بہت سی container images میں معمول ہے، وہاں دونوں کو مختلف hosts کے طور پر match کیا جاتا ہے۔ ایسی صورت میں 127.0.0.1 سے connect کرنے والی ایپلیکیشن کو درست password کے باوجود ERROR 1045 (28000): Access denied for user 'appuser'@'127.0.0.1' (using password: YES) کے ساتھ reject کر دیا جاتا ہے۔

اس لیے اپنی application کو host localhost، user appuser، اور database appdb پر point کریں؛ اسے کبھی root پر point نہ کریں۔ PHP کا mysqli اور PDO، دونوں، اس وقت Unix socket استعمال کرتے ہیں جب host literal string localhost ہو۔ یہ اسی account سے match کرتا ہے جسے آپ نے ابھی بنایا ہے۔ اگر کوئی framework numeric TCP host پر اصرار کرے تو user کو اس طریقے کے مطابق بنائیں جس سے framework واقعی connect کرتا ہے: 'appuser'@'127.0.0.1'، یا @'%' صرف اس صورت میں جب database تک کسی دوسری machine سے رسائی ضروری ہو، اور اس کے ساتھ firewall rule بھی لگائیں۔

مرحلہ 8 - Certbot کے ساتھ HTTPS شامل کریں

سادہ HTTP کے ذریعے login form پیش کرنے سے passwords plain text میں منتقل ہوتے ہیں، اور ہر جدید browser صفحے کو "Not secure" قرار دیتا ہے۔ Certbot یہ کام ایک command سے کر دیتا ہے۔ اسے Apache plugin کے ساتھ install کریں:

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

Certbot یہاں دو plugins استعمال کرتا ہے۔ apache authenticator آپ کے چلتے ہوئے Apache کے ذریعے عارضی طور پر challenge file پیش کرکے یہ ثابت کرتا ہے کہ domain آپ کے کنٹرول میں ہے، جبکہ apache installer پھر آپ کے virtual host کو rewrite کرکے 443 block شامل کرتا ہے، اسے نئے certificate کی طرف point کرتا ہے، اور default طور پر تمام HTTP traffic کو HTTPS پر redirect کرتا ہے۔ Certbot 2.0 کے بعد redirect سے متعلق سوال نہیں آتا؛ اگر plain HTTP پیش کرتے رہنا ہو تو --no-redirect pass کریں۔ چونکہ آپ نے مرحلہ 5 میں حقیقی ServerName set کیا تھا، اس لیے Certbot domain خودکار طور پر detect کر لیتا ہے۔ Certificates 90 دن تک valid رہتے ہیں، اور package ایک systemd timer install کرتا ہے جو انہیں renew کرتا ہے؛ sudo certbot renew --dry-run کے ذریعے timer verify کریں۔ اس کا اختتام Congratulations, all simulated renewals succeeded پر ہونا چاہیے۔

Challenge، renewal timer، DNS اور firewall requirements کی مکمل وضاحت کے لیے companion guide Apache پر Certbot کے ساتھ مفت Let's Encrypt TLS certificates جاری کرنا دیکھیں۔

بیک اپ، اپ گریڈ اور سکیورٹی سخت بنانا

اپنی state محفوظ رکھنے والی دو چیزوں کا بیک اپ لیں: databases اور web root۔ رات کے وقت لیا جانے والا logical dump سب سے آسان قابلِ اعتماد طریقہ ہے، sudo sh -c 'mysqldump --all-databases --single-transaction | gzip > /root/db-$(date +%F).sql.gz'، پھر اسے server سے باہر کسی مقام پر copy کریں۔ پوری pipeline کو sudo sh -c میں wrap کرنا اہم ہے: اس کے بغیر shell > /root/... redirect کو آپ کے اپنے user کے طور پر چلاتی ہے اور Permission denied کے ساتھ ناکام ہو جاتی ہے، کیونکہ صرف mysqldump کو sudo وراثت میں ملا تھا۔ --single-transaction InnoDB tables کو lock کیے بغیر ان کا consistent snapshot بناتا ہے۔ اسے /var/www اور /etc/apache2/sites-available کے tar کے ساتھ استعمال کریں، اور ان files سے نئے VPS پر پوری stack دوبارہ بنائی جا سکتی ہے۔

Upgrades معمول کا sudo apt update && sudo apt upgrade ہیں۔ سب سے زیادہ مسئلہ PHP version bump سے پیدا ہوتا ہے۔ جب مستقبل میں Ubuntu کا default PHP 8.4 ہو جائے، تو apt، 8.3 کے ساتھ php8.4-fpm بھی install کر سکتا ہے، socket /run/php/php8.4-fpm.sock بن جاتا ہے، اور آپ کی Apache config اب بھی 8.3 والے socket کی طرف اشارہ کرتی رہتی ہے۔ نئی conf کو enable (sudo a2enconf php8.4-fpm) کریں اور پرانی کو disable کریں، ورنہ معمول کے upgrade کے بعد آپ کی site Primary script unknown واپس کرنا شروع کر دے گی۔ چونکہ PHP releases کسی LTS distro کے مقابلے میں زیادہ تیزی سے بدلتی ہیں، اس لیے patch version کو pin کرنے کے بجائے موجودہ PHP release notes دیکھیں۔

پہلے ہی دن سکیورٹی سخت بنانے کے دو اقدامات مفید ہیں۔ اول، server پر SSH کو monitor کرنے والا Fail2Ban لگائیں۔ public VPS پر چند منٹ کے اندر automated login attempts شروع ہو جاتی ہیں، اور ایک چھوٹا jail ban سے پہلے ہزاروں کوششوں کو چند کوششوں تک محدود کر دیتا ہے۔ دوم، اگر آپ files کو ہاتھ سے edit کرنے کے بجائے Apache virtual hosts، MariaDB databases اور users کو browser کے ذریعے manage کرنا چاہتے ہیں، تو Webmin کا web-based control panel اسی stack کے اوپر چلتا ہے اور انہی config files کو manage کرتا ہے جو آپ نے ابھی لکھی ہیں۔ ان میں سے کوئی بھی اجزا کو سمجھنے کی ضرورت ختم نہیں کرتا، لیکن دونوں روزمرہ کے انتظامی کام کو آسان بنا دیتے ہیں۔

ناکامی کی صورتیں، اور نظر آنے والے پیغامات

پہلے سے موجود صفحہ ختم نہیں ہوتا۔ آپ نے virtual host میں ترمیم کی، اسے reload کیا، لیکن browser اب بھی "Apache2 Ubuntu Default Page" اور اس کا "It works!" banner دکھاتا ہے۔ Apache پہلے matching virtual host سے صفحہ فراہم کرتا ہے۔ جب کوئی ServerName درخواست سے match نہیں کرتا تو حروف تہجی کے اعتبار سے پہلی config استعمال ہوتی ہے؛ 000-default.conf، testapp.conf سے پہلے آتا ہے۔ یا تو درخواست کا host name آپ کے ServerName سے match نہیں کرتا، یا آپ نے کبھی sudo a2dissite 000-default نہیں چلایا۔ default کو disable کریں، sudo systemctl reload apache2، اور apache2ctl -S سے تصدیق کریں۔ یہ vhost map دکھاتا ہے اور بتاتا ہے کہ default کا اختیار کس config کے پاس ہے۔ browser cache بھی صاف کریں؛ پرانے صفحے کا cache شدہ 200 response برقرار رہ سکتا ہے۔

ایک .php فائل چلنے کے بجائے download ہو جاتی ہے۔ آپ info.php کھولتے ہیں، لیکن browser خام <?php source والی فائل download کر لیتا ہے یا اسے plain text کے طور پر دکھاتا ہے۔ Apache اس فائل کو static asset کے طور پر فراہم کر رہا ہے، کیونکہ PHP handler منسلک نہیں ہے، آپ نے sudo a2enmod proxy_fcgi یا sudo a2enconf php8.3-fpm چھوڑ دیا، یا اس کے بعد Apache restart نہیں کیا۔ تینوں کام چلائیں (Step 4) اور دوبارہ load کریں۔ apache2ctl -M | grep fcgi سے تصدیق کریں کہ module load ہے؛ اس میں proxy_fcgi_module درج ہونا چاہیے۔ یہ source-code leak ہے، صرف ظاہری خرابی نہیں۔ اس لیے server پر حقیقی مواد رکھنے سے پہلے اسے درست کریں۔

ERROR 1698 (28000): Access denied for user 'root'@'localhost'۔ آپ نے mysql -u root یا mariadb -u root، sudo کے بغیر چلایا۔ root account unix_socket authentication استعمال کرتا ہے، اس لیے یہ آپ کو صرف اس وقت قبول کرتا ہے جب آپ کا OS user واقعی root ہو۔ درست طریقہ sudo mysql ہے؛ -u root نہیں، password بھی نہیں۔ یہ پیغام socket authentication کے درست کام کرنے کا متوقع نتیجہ ہے، خراب installation کی علامت نہیں۔

ERROR 1045 (28000): Access denied for user 'appuser'@'127.0.0.1' application سے، درست password کے باوجود۔ account 'appuser'@'localhost' کے طور پر موجود ہے، لیکن آپ کی app TCP کے ذریعے 127.0.0.1 سے connect کر رہی ہے۔ اس server پر host-name resolution disabled ہے (skip-name-resolve)، اس لیے MariaDB دونوں کو مختلف hosts سمجھتا ہے: localhost Unix socket ہے، جبکہ 127.0.0.1 TCP ہے۔ app کو host localhost پر point کریں تاکہ یہ socket استعمال کرے اور account سے match ہو، یا دوسرا account 'appuser'@'127.0.0.1' بنائیں، اگر framework صرف TCP استعمال کرتا ہے۔

AH01071: Got error 'Primary script unknown'، /var/log/apache2/testapp-error.log میں، جبکہ browser File not found. دکھاتا ہے۔ Apache نے درخواست PHP-FPM کو دے دی، لیکن FPM کو Apache کی فراہم کردہ path پر script نہیں ملی۔ اس کی دو عام وجوہات ہیں: config میں FPM socket ایسے PHP version کی طرف اشارہ کرتا ہے جو installed نہیں ہے، مثلاً upgrade کے بعد php8.4 socket موجود ہے جبکہ صرف 8.3 چل رہا ہے؛ یا فائل واقعی موجود نہیں، کیونکہ DocumentRoot اور اصل directory ایک دوسرے سے مختلف ہیں۔ ls -l /run/php/ سے تصدیق کریں کہ socket موجود ہے۔ DocumentRoot اس مقام سے match ہونا چاہیے جہاں فائل موجود ہے۔ پھر php8.3-fpm اور apache2 دونوں restart کریں۔

AH00558: apache2: Could not reliably determine the server's fully qualified domain name ہر restart پر۔ یہ بے ضرر warning ہے، error نہیں۔ Apache بتا رہا ہے کہ کوئی global ServerName مقرر نہیں ہے۔ /etc/apache2/conf-available/servername.conf میں ServerName your.domain لکھ کر اور sudo a2enconf servername چلا کر اسے خاموش کریں۔

(98)Address already in use: AH00072: make_sock: could not bind to address 0.0.0.0:80، جب Apache start ہوتا ہے۔ کوئی دوسرا web server پہلے ہی port 80 استعمال کر رہا ہے۔ اکثر یہ پچھلے تجربے سے رہ جانے والا nginx ہوتا ہے۔ sudo ss -ltnp | grep :80 سے اس process کو تلاش کریں، پھر Apache start کرنے سے پہلے دوسری service کو stop اور disable کریں۔

FAQ

mod_php یا PHP-FPM — مجھے کون سا استعمال کرنا چاہیے؟

PHP-FPM استعمال کریں۔ mod_php ہر Apache process میں interpreter شامل کرتا ہے اور سست prefork MPM کو لازمی بنا دیتا ہے، اس لیے static image پیش کرتے وقت بھی Apache پر PHP کا اضافی بوجھ رہتا ہے۔ PHP-FPM، PHP کو الگ اور آزادانہ طور پر tune کیے گئے pool کے طور پر چلاتا ہے جس تک Apache socket کے ذریعے پہنچتا ہے۔ یہ تیز threaded event MPM کے ساتھ کام کرتا ہے اور بعد میں nginx پر منتقل کرنا بھی آسان رہتا ہے۔ یہی جدید default ہے؛ mod_php صرف ایسی legacy app کے لیے موزوں ہے جو کسی in-process behaviour پر منحصر ہو۔

میرا browser PHP file چلانے کے بجائے download کیوں کرتا ہے؟

Apache .php file کو static download سمجھ رہا ہے کیونکہ اس کے ساتھ PHP handler منسلک نہیں ہے۔ Ubuntu 24.04 پر FPM کے ساتھ اس کا مطلب ہے کہ آپ نے sudo a2enmod proxy_fcgi، sudo a2enconf php8.3-fpm یا اس کے بعد Apache restart میں سے کوئی مرحلہ چھوڑ دیا ہے۔ تینوں commands چلائیں اور پھر reload کریں۔ اس کے بعد apache2ctl -M | grep fcgi سے تصدیق کریں کہ proxy_fcgi_module درج ہے۔ مسئلہ حل ہونے تک server source code افشا کر رہا ہے، اس لیے اسے فوری طور پر درست کریں۔

درست password کے باوجود MariaDB میں root access denied کیوں آتا ہے؟

کیونکہ password موجود نہیں ہے، Ubuntu کا MariaDB root account کو unix_socket کے ذریعے authenticate کرتا ہے اور اسے operating-system root user سے وابستہ رکھتا ہے۔ عام shell سے mysql -u root چلانے پر design کے مطابق ERROR 1698 (28000): Access denied for user 'root'@'localhost' واپس آتا ہے۔ اس کے بجائے sudo mysql سے connect کریں، اور کسی بھی application کے لیے root دوبارہ استعمال کرنے کے بجائے الگ password-authenticated user بنائیں۔

اپنی LAMP site میں HTTPS کیسے شامل کروں؟

certbot اور python3-certbot-apache install کریں، domain کا A record server کی طرف point کریں، پھر sudo certbot --apache چلائیں۔ apache authenticator آپ کے چلتے ہوئے Apache کے ذریعے domain control کی تصدیق کرتا ہے، virtual host کو port 443 کے لیے rewrite کرتا ہے، اور automatic renewal قائم کرتا ہے۔ مکمل Certbot اور Apache walk-through میں challenge، renewal timer اور عام failure modes کی وضاحت موجود ہے۔

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