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

Ubuntu 24.04 پر LAMP stack کیسے انسٹال کریں

Ubuntu 24.04 پر Apache, MariaDB, PHP 8.3 اور PHP-FPM کے ساتھ مکمل LAMP stack ترتیب دیں۔ اس میں Certbot کے ذریعے HTTPS اور vhost کی مکمل معلومات شامل ہیں۔

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

ایک LAMP stack ایک Ubuntu 24.04 server پر چار حصوں پر مشتمل ہوتا ہے: بنیادی نظام کے طور پر Linux، HTTP کے لیے Apache، ڈیٹا کے لیے MariaDB، اور کوڈ چلانے کے لیے PHP 8.3۔ اس عمل کے اختتام پر آپ کے پاس ایک نام پر مبنی virtual host ہوگا جو ایپلی کیشن ڈائریکٹری سروس کرے گا، ایک ڈیٹا بیس ہوگا جس میں کم از权限 (least-privilege) والا مخصوص صارف ہوگا، PHP-FPM کے ذریعے Apache کے ساتھ منسلک PHP ہوگا، اور اس کے اوپر Let's Encrypt کا مفت سرٹیفکیٹ ہوگا۔

اس انسٹالیشن میں چار apt کمانڈز شامل ہیں۔ اس گائیڈ کا زیادہ تر حصہ ان حصوں کے درمیان کنکشن بنانے اور ان چھوٹی غلطیوں کے بارے میں ہے جو نئے stack کو خالی صفحہ دکھانے، آپ کے source code کو ڈاؤن لوڈ کے لیے براؤزر میں بھیجنے، یا انسٹال شدہ ڈیٹا بیس تک رسائی روکنے پر مجبور کر دیتی ہیں۔ ان تمام غلطیوں کی مخصوص علامات ہوتی ہیں، اور ہر ایک کا نام نیچے دیے گئے متن کے ساتھ درج ہے۔

Prerequisites اور اہم احتیاطی تدابیر

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

Certbot کے درست کام کرنے کے لیے درج ذیل دو شرائط کا پورا ہونا ضروری ہے:

  1. آپ کے پاس ایک domain name ہونا چاہیے جس کا A record VPS کے public IP کی طرف اشارہ کرتا ہو — Let's Encrypt اسی نام پر HTTP کے ذریعے validation کرتا ہے، اور صرف IP address پر certificate حاصل نہیں کیا جا سکتا۔
  2. پورٹس 80 اور 443 انٹرنیٹ سے قابل رسائی ہونی چاہئیں، جس کا مطلب ہے کہ آپ کو انہیں کنٹرول پینل میں network firewall میں اور ساتھ ہی مشین پر ufw میں بھی کھولنا ہوگا۔

DNS تبدیلیاں propagate ہونے میں 1 گھنٹے تک کا وقت لے سکتی ہیں، اس لیے پہلے A record سیٹ کر دیں تاکہ ضرورت پڑنے پر یہ دستیاب ہو۔

Step 1 - Apache install karein aur default page ki tasdeeq karein

sudo apt update
sudo apt install -y apache2

apt aap ke liye service ko start aur enable kar deta hai. Isay check karein:

systemctl status apache2

Aap ko active (running) wali line nazar aani chahiye. Ab browser mein http://YOUR_SERVER_IP/ open karein. "It works!" banner ke saath Apache2 Ubuntu Default Page ka nazar aana sahi natija hai — yeh is baat ka saboot hai ke Apache kaam kar raha hai, yeh koi ghalati nahi hai. Woh page /var/www/html/index.html par maujood hai aur default virtual host 000-default.conf ke zariye serve kiya jata hai. Aap baad mein in dono ko disable kar denge; filhal inka hona hi zaroori hai.

Agar page load nahi ho raha lekin systemctl dikhata hai ke process chal raha hai, to iska matlab hai ke firewall rukawat ban raha hai. Agla step wahi hai.

Step 2 - HTTP اور HTTPS کے لیے firewall کھولیں

apache2 package تین ufw application profiles رجسٹر کرتا ہے۔ ان کی فہرست یہ ہے:

sudo ufw app list

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

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

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

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

sudo apt install -y mariadb-server
systemctl status mariadb

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

sudo mysql_secure_installation

Enter بٹن دبانے کے بجائے prompts کو پڑھنا بہتر ہے۔ جب current root password پوچھا جائے، تو Enter دبائیں — ابھی کوئی پاس ورڈ موجود نہیں ہے۔ جب "Switch to unix_socket authentication?" پوچھا جائے، تو اس کا جواب دینے سے کوئی فرق نہیں پڑے گا کیونکہ اس package پر یہ پہلے سے فعال ہے، اس لیے n دبائیں۔ اگلے پیراگراف میں دی گئی وجہ کی بنا پر "Change the root password?" کے لیے n منتخب کریں، پھر باقی سوالات کے لیے Y کا جواب دیں: anonymous users کو ہٹائیں، remote root login کو منع کریں، test database کو ختم کریں، اور privilege tables کو reload کریں۔

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

sudo mysql

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

Step 4 - PHP 8.3 اور PHP-FPM انسٹال کریں

Ubuntu 24.04 میں پیشလာؤ PHP ورژن 8.3 ہے۔ FPM پروسس مینیجر اور وہ extensions انسٹال کریں جو عام طور پر کسی بھی app کے لیے ضروری ہوتی ہیں:

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

Apache، proxy_fcgi module کے ذریعے FPM سے رابطہ کرتا ہے۔ اسے enable کریں، FPM package کے ذریعے فراہم کردہ configuration کو 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 کرتا ہے۔ اس کا بنیادی حصہ کسی بھی .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 کو edit نہیں کریں گے؛ یہ پہلے سے درست ہوتی ہے۔ لیکن socket path کا علم ہونا آپ کو بعد میں "PHP downloads instead of running" اور "Primary script unknown" جیسی غلطیوں (failures) کو حل کرنے میں مدد دے گا — یہ دونوں مسائل تب آتے ہیں جب Apache اور FPM اس socket یا اس کے پیچھے موجود file کے بارے میں متفق نہیں ہوتے۔

Step 5 - آپ کی ایپ کے لیے نام پر مبنی (name-based) ورچوئل ہوسٹ

نام پر مبنی ورچوئل ہوسٹنگ ایک ہی 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

ملکیت (Ownership) اہم ہے۔ Ubuntu پر Apache اور PHP-FPM دونوں www-data صارف کے طور پر چلتے ہیں، اس لیے وہ فائلیں جنہیں ویب سرور کو پڑھنے کی ضرورت ہے — اور وہ ڈائریکٹریز جن میں ایپ کو لکھنے کی ضرورت ہے، جیسے کہ 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 ایپلی کیشنز کو خوبصورت URLs کے لیے ضرورت ہوتی ہے؛ اگر آپ کی ایپ کو اس کی ضرورت نہیں ہے، تو تھوڑی رفتار میں اضافے کے لیے اسے None میں ڈال دیں۔ اس سائٹ کو فعال کریں، ڈیفالٹ سائٹ کو غیر فعال کریں، کنفیگریشن چیک کریں، اور ری لوڈ کریں:

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

apache2ctl configtest کو Syntax OK پرنٹ کرنا چاہیے۔ a2dissite 000-default لائن وہ ہے جسے لوگ بھول جاتے ہیں، اور اسی وجہ سے ڈیفالٹ پیج بعد میں پھنسا ہوا محسوس ہوتا ہے — اس کی تفصیل failures سیکشن میں موجود ہے۔

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

app root میں ایک لائن پر مشتمل 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، تمام لوڈ شدہ extensions، file paths، اور environment details ظاہر کرتا ہے — یہ ان لوگوں کے لیے ایک تحفہ ہے جو server پر کسی معلوم vulnerability والے version کی تلاش میں ہوتے ہیں۔ یہ صرف ایک ٹیسٹ ہے، کوئی feature نہیں۔ جیسے ہی آپ پیج دیکھ لیں، اسے حذف کر دیں۔ اگر ٹیبل کے بجائے آپ کا browser info.php کو download کرنے کا آپشن دے، تو اس کا مطلب ہے کہ PHP، Apache کے ساتھ منسلک نہیں ہے؛ اس سے پہلے کہ آپ کچھ اور کریں، failures section پر جائیں۔

Step 7 - Create the app database and a least-privilege user

Open the database as the socket-authenticated root:

sudo mysql

Then create one database and one user scoped to exactly that database:

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;

Three deliberate choices here. utf8mb4 is real four-byte UTF-8 — the old utf8 alias silently truncates emoji and some CJK characters, so always use utf8mb4. The grant is on appdb.*, not *.*: this user can touch its own database and nothing else, so a SQL-injection hole in the app cannot read every other site's tables. And 'appuser'@'localhost' restricts the account to connections originating on the box itself.

Test it as that user:

mysql -u appuser -p appdb

It asks for the password and drops you at a MariaDB [appdb]> prompt. Notice there is no -h flag — leave it off and the client connects over the local Unix socket, which is exactly what MariaDB counts as localhost. One gotcha worth knowing: to MySQL and MariaDB, localhost means the Unix socket and 127.0.0.1 means a TCP connection. On a stock Ubuntu 24.04 MariaDB the server still resolves a TCP connection from 127.0.0.1 back to localhost, so both match the account — but on servers with skip-name-resolve enabled (a common performance tweak, and the norm in many container images), the two are matched as different hosts, and an app that dials 127.0.0.1 is refused with ERROR 1045 (28000): Access denied for user 'appuser'@'127.0.0.1' (using password: YES) even when the password is correct.

So point your application at host localhost, user appuser, database appdb — never at root. PHP's mysqli and PDO both switch to the Unix socket when the host is the literal string localhost, matching the account you just created. If a framework insists on a numeric TCP host, create the user to match how it actually connects — 'appuser'@'127.0.0.1', or @'%' (paired with a firewall rule) only if it must reach the database from another machine.

Step 8 - Add HTTPS with Certbot

Serving a login form over plain HTTP sends passwords in clear text, and every modern browser flags the page as "Not secure". Certbot fixes that in one command. Install it with the Apache plugin:

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

Certbot uses two plugins here. The apache authenticator proves you control the domain by briefly serving a challenge file through your running Apache, and the apache installer then rewrites your virtual host to add the 443 block, points it at the new certificate, and redirects all HTTP traffic to HTTPS by default — since Certbot 2.0 there is no redirect question; pass --no-redirect if you need to keep serving plain HTTP. Because you set a real ServerName in Step 5, Certbot detects the domain automatically. Certificates last 90 days and the package installs a systemd timer that renews them; verify the timer with sudo certbot renew --dry-run, which should end in Congratulations, all simulated renewals succeeded.

For the full walk-through of the challenge, the renewal timer, and the DNS and firewall requirements, see the companion guide on issuing free Let's Encrypt TLS certificates with Certbot on Apache.

Backups, upgrades, and hardening

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

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

پہلے دن دو hardening اقدامات کرنا فائدہ مند ہے۔ پہلا، سرور پر Fail2Ban SSH monitoring لگائیں — ایک public VPS پر منٹوں کے اندر خودکار login attempts شروع ہو جاتے ہیں، اور ایک چھوٹا jail ہزاروں کوششوں کو ban ہونے سے پہلے چند کوششوں تک محدود کر دیتا ہے۔ دوسرا، اگر آپ Apache virtual hosts، MariaDB databases، اور users کو فائلوں کو دستی طور پر ایڈٹ کرنے کے بجائے براؤزر کے ذریعے مینیج کرنا چاہتے ہیں، تو Webmin web-based control panel اسی stack پر کام کرتا ہے اور انہی config فائلوں کو کنٹرول کرتا ہے جو آپ نے ابھی لکھی ہیں۔ ان میں سے کوئی بھی چیز ان حصوں کی سمجھ بوجھ کا متبادل نہیں ہے، لیکن دونوں روزانہ کے کاموں میں دشواری کو کم کرتے ہیں۔

Failure modes, with the strings you will see

ڈیفالٹ پیج ختم نہیں ہوگا۔ آپ نے اپنا virtual host ایڈٹ کیا اور ریلود کیا، لیکن براؤزر اب بھی "Apache2 Ubuntu Default Page" اور اس کا "It works!" بینر دکھا رہا ہے۔ Apache پہلا میچ ہونے والا virtual host سروس کرتا ہے۔ جب کوئی ServerName ریکوئسٹ سے میچ نہیں کرتا، تو حروفِ تہجی (alphabetically) کے لحاظ سے پہلا کنفیگریشن جیت جاتا ہے — 000-default.conf، testapp.conf سے پہلے آتا ہے۔ یا تو ریکوئسٹ کا host name آپ کے ServerName سے میچ نہیں کرتا، یا آپ نے کبھی sudo a2dissite 000-default نہیں چلایا۔ ڈیفالٹ کو ڈس ایبل کریں، sudo systemctl reload apache2، اور apache2ctl -S کے ساتھ کنفرم کریں، جو vhost میپ پرنٹ کرتا ہے اور دکھاتا ہے کہ کون سا کنفیگریشن ڈیفالٹ کا مالک ہے۔ براؤزر کیش (cache) بھی کلیئر کریں؛ پرانے پیج کا کیش شدہ 200 اسٹیٹس برقرار رہ سکتا ہے۔

info.php فائل چلنے کے بجائے ڈاؤن لوڈ ہو جاتی ہے۔ آپ info.php کھولتے ہیں اور براؤزر فائل ڈاؤن لوڈ کر لیتا ہے جس میں خام (raw) <?php سورس ہوتا ہے، یا اسے سادہ ٹیکسٹ کے طور پر دکھاتا ہے، بجائے اس کے کہ اسے رن کرے۔ Apache اس فائل کو static asset کے طور پر سروس کر رہا ہے کیونکہ PHP handler منسلک نہیں ہے — آپ نے sudo a2enmod proxy_fcgi، یا sudo a2enconf php8.3-fpm چھوڑ دیا ہے، یا اس کے بعد Apache کو ری اسٹارٹ نہیں کیا۔ تینوں (Step 4) چلائیں اور ریلود کریں۔ apache2ctl -M | grep fcgi کے ساتھ کنفرم کریں کہ ماڈیول لوڈ ہو گیا ہے، جس میں proxy_fcgi_module لسٹ ہونا چاہیے۔ یہ source-code leak ہے، کوئی ظاہری بگ نہیں، اس لیے سرور پر کوئی حقیقی ڈیٹا رکھنے سے پہلے اسے ٹھیک کریں۔

ERROR 1698 (28000): Access denied for user 'root'@'localhost'. آپ نے sudo کے بغیر mysql -u root یا mariadb -u root چلایا ہے۔ root اکاؤنٹ unix_socket authentication استعمال کرتا ہے، اس لیے یہ آپ کو صرف تب قبول کرتا ہے جب آپ کا OS user درحقیقت root ہو۔ اس کا حل sudo mysql ہے — کوئی -u root نہیں، کوئی پاس ورڈ نہیں۔ یہ میسج socket auth کے صحیح کام کرنے کی وجہ سے متوقع رویہ ہے، یہ خراب انسٹالیشن نہیں ہے۔

درست پاس ورڈ کے ساتھ ایپلی کیشن سے ERROR 1045 (28000): Access denied for user 'appuser'@'127.0.0.1'۔ اکاؤنٹ 'appuser'@'localhost' کے طور پر موجود ہے، لیکن آپ کی ایپ TCP کے ذریعے 127.0.0.1 پر کنیکٹ ہو رہی ہے جہاں host-name resolution ڈس ایبل ہے (skip-name-resolve)، اس لیے MariaDB ان دونوں کو مختلف ہوسٹس کے طور پر میچ کرتا ہے — localhost Unix socket ہے، 127.0.0.1 TCP ہے۔ ایپ کو host localhost پر پوائنٹ کریں تاکہ یہ socket استعمال کرے اور اکاؤنٹ سے میچ ہو جائے، یا اگر فریم ورک صرف TCP استعمال کرتا ہے تو دوسرا اکاؤنٹ 'appuser'@'127.0.0.1' بنائیں۔

/var/log/apache2/testapp-error.log میں AH01071: Got error 'Primary script unknown'، جبکہ براؤزر File not found. دکھا رہا ہے۔ Apache نے ریکوئسٹ PHP-FPM کو دے دی، لیکن FPM اس اسکرپٹ کو اس پاتھ پر نہیں پا سکا جو Apache نے دیا تھا۔ دو عام وجوہات: آپ کے کنفیگریشن میں FPM socket اس PHP ورژن کی طرف اشارہ کرتا ہے جو انسٹال نہیں ہے (اپ گریڈ کے بعد php8.4 socket جبکہ صرف 8.3 چل رہا ہے)، یا فائل واقعی وہاں موجود نہیں ہے کیونکہ DocumentRoot اور اصل ڈائریکٹری میں فرق ہےate۔ ls -l /run/php/ کے ساتھ چیک کریں کہ socket موجود ہے، کنفرم کریں کہ DocumentRoot اس جگہ سے میچ کرتا ہے جہاں فائل موجود ہے، اور php8.3-fpm اور apache2 دونوں کو ری اسٹارٹ کریں۔

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

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

FAQ

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

PHP-FPM استعمال کریں۔ mod_php ہر Apache process کے اندر ایک interpreter شامل کر دیتا ہے اور یہ slow prefork MPM کے استعمال پر مجبور کرتا ہے، جس کی وجہ سے Apache پر static image serve کرتے وقت بھی PHP کا overhead رہتا ہے۔ PHP-FPM، PHP کو ایک علیحدہ اور independently tuned pool کے طور پر چلاتا ہے جسے Apache socket کے ذریعے access کرتا ہے۔ یہ تیز رفتار threaded event MPM کے ساتھ کام کرتا ہے اور بعد میں nginx پر منتقل کرتے وقت بھی تبدیل نہیں ہوتا۔ یہ جدید default ہے؛ mod_php صرف ان legacy apps کے لیے مفید ہے جو in-process behaviour پر منحصر ہوں۔

میرا browser PHP فائل کو run کرنے کے بجائے download کیوں کر رہا ہے؟

Apache .php فائل کو static download کے طور پر treat کر رہا ہے کیونکہ اس کے ساتھ کوئی PHP handler منسلک نہیں ہے۔ Ubuntu 24.04 پر FPM کے ساتھ اس کا مطلب ہے کہ آپ sudo a2enmod proxy_fcgi، sudo a2enconf php8.3-fpm، یا Apache restart کرنا بھول گئے ہیں۔ ان تینوں کو run کریں اور reload کریں، پھر apache2ctl -M | grep fcgi سے verify کریں کہ کیا proxy_fcgi_module فہرست میں موجود ہے۔ جب تک آپ اسے ٹھیک نہیں کرتے، server سے source code leak ہو رہا ہے، اس لیے اسے فوری حل کریں۔

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

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

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

certbot اور python3-certbot-apache install کریں، domain کے A record کو server پر point کریں، اور پھر sudo certbot --apache run کریں۔ Apache authenticator آپ کے running Apache کے ذریعے domain control کو ثابت کرتا ہے، اور installer port 443 کے لیے virtual host کو rewrite کرتا ہے اور automatic renewal سیٹ اپ کرتا ہے۔ full Certbot اور Apache walk-through اس چیلنج، renewal timer، اور عام failure modes کی وضاحت کرتا ہے۔

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