نحوه نصب LEMP stack در اوبونتو
در این مقاله میخوانید
در این مقاله از آموزش اوبونتو گامبهگام نحوه نصب و راهاندازی LEMP روی سرور اوبونتو را بررسی میکنیم و در ادامه توضیح میدهیم که چگونه Nginx، MySQL و PHP را نصب و برای اجرا آماده کنید. LEMP در واقع مجموعهای از ابزارهای نرمافزاری است که به شما کمک میکند سایتها و وباپلیکیشنهای پویا و نوشتهشده با PHP را اجرا کنید. در این ساختار، لینوکس بهعنوان سیستمعامل، Nginx بهعنوان وبسرور، MySQL برای ذخیره دادهها و PHP برای پردازش محتوای پویا به کار گرفته میشوند.
پیشنیازهای نصب و راهاندازی LEMP روی سرور اوبونتو
برای شروع، پیشنهاد میشود که روی اوبونتو از یک کاربر غیر روت با دسترسی sudo استفاده کنید و فایروال UFW نیز فعال باشد.
نکته:
این آموزش بر پایه Ubuntu 22.04 LTS و PHP 8.1 نوشته شده است. اگر از Ubuntu 24.04 LTS استفاده میکنید، نسخه PHP را در دستورات از php8.1-fpm به php8.3-fpm تغییر دهید و مسیر سوکت PHP-FPM را نیز مطابق نسخه جدید (مانند /run/php/php8.3-fpm.sock) بهروزرسانی کنید.
۱. نصب وبسرور Nginx
برای نمایش صفحات وب به کاربران، قرار است از Nginx استفاده کنیم؛ یک وبسرور قدرتمند و پرکاربرد که عملکرد بسیار خوبی دارد. برای نصب آن از مدیر بسته APT کمک میگیریم.
ابتدا فهرست مخازن سیستم را بهروزرسانی کنید:
sudo apt update
سپس با دستور زیر Nginx را نصب کنید:
sudo apt install nginx
در صورت نمایش پیام تایید، کلید Y و سپس ENTER را بزنید. بعد از پایان نصب، وبسرور Nginx روی اوبونتوی شما فعال و در حال اجرا خواهد بود.
برای اطمینان از اجرا شدن سرویس، وضعیت آن را بررسی کنید:
sudo systemctl status nginx
در خروجی، باید وضعیت (Active (running را مشاهده کنید. جالب است بدانید که در اوبونتو، Nginx بهصورت پیشفرض بعد از نصب فعال میشود.
Output nginx.service - A high performance web server and a reverse proxy server Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled) Active: active (running) since...
فعال کردن دسترسی HTTP در فایروال
Nginx هنگام نصب، چند پروفایل برای UFW ثبت میکند. ابتدا لیست پروفایلهای موجود را ببینید:
sudo ufw app list Output Available applications: Nginx Full Nginx HTTP Nginx HTTPS OpenSSH
در حال حاضر هنوز SSL راهاندازی نشده است، پس فقط دسترسی HTTP روی پورت 80 را فعال کنید:
sudo ufw allow 'Nginx HTTP'
برای بررسی وضعیت فایروال:
sudo ufw status
اگر در خروجی مشاهده کردید که Nginx HTTP مجاز شده، یعنی دسترسی HTTP برای سرور فعال است.
Output Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere Nginx HTTP ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) Nginx HTTP (v6) ALLOW Anywhere (v6) تست اجرای Nginx
برای تست، در مرورگر آدرس دامنه سرور خود را وارد کنید:
http://your_domain
اگر هنوز دامنهای متصل نکردهاید و IP عمومی سرور را نمیدانید، میتوانید با این دستورات IP را پیدا کنید:
ip addr show
یا:
hostname -I
همچنین میتوانید IP قابل دسترس از اینترنت را با دستور زیر بهدست آورید:
curl -4 icanhazip.com
حالا IP بهدست آمده را در مرورگر وارد کنید. اگر صفحه پیشفرض Nginx نمایش داده شد، یعنی نصب Nginx و فعال شدن ترافیک HTTP با موفقیت انجام شده است.
http://<server_domain_or_IP>
۲. نصب MySQL
در این مرحله باید MySQL را نصب کنید تا ذخیره و مدیریت دادههای سایت انجام شود. MySQL یکی از رایجترین سیستمهای مدیریت پایگاه داده برای محیطهای مبتنی بر PHP است.
مثل قبل، با استفاده از apt برنامه را نصب کنید:
sudo apt install mysql-server
وقتی پیام تایید نمایش داده شد، کلید Y و سپس Enter را بزنید تا نصب انجام شود. بعد از اتمام نصب، برای افزایش امنیت و حذف تنظیمات پیشفرض ناامن، اسکریپت امنیتی MySQL را اجرا کنید:
sudo mysql_secure_installation
در این مرحله از شما پرسیده میشود که آیا میخواهید افزونه VALIDATE PASSWORD را فعال کنید یا خیر؟
Output VALIDATE PASSWORD COMPONENT can be used to test passwords and improve security. It checks the strength of password and allows the users to set only those passwords which are secure enough. Would you like to setup VALIDATE PASSWORD component? Press y|Y for Yes, any other key for No:
اگر میخواهید فعال شود، Y بزنید و در غیر این صورت هر کلید دیگری را فشار دهید.
نکته:
فعال کردن این قابلیت به انتخاب شما بستگی دارد. اگر آن را فعال کنید، MySQL فقط رمزعبورهایی را قبول میکند که استاندارد امنیتی مشخصی داشته باشند. غیرفعال کردن آن هم مشکلی ایجاد نمیکند، اما بهتر است همیشه از رمزهای قوی و یکتا استفاده کنید.
اگر فعالش کنید، باید سطح سختگیری رمز عبور را مشخص کنید. برای مثال سطح ۲ قویترین حالت است و اگر رمز شامل عدد، حروف کوچک و بزرگ و کاراکتر خاص نباشد، خطا میدهد.
Output There are three levels of password validation policy: LOW Length >= 8 MEDIUM Length >= 8, numeric, mixed case, and special characters STRONG Length >= 8, numeric, mixed case, special characters and dictionary file Please enter 0 = LOW, 1 = MEDIUM and 2 = STRONG: 1
پس از این مرحله، باید برای کاربر root دیتابیس یک رمز عبور تعیین و تایید کنید. توجه داشته باشید که این کاربر با کاربر root سیستم فرق دارد و دسترسی کامل مدیریتی به دیتابیس دارد. حتی اگر روش احراز هویت MySQL نیاز به رمز نداشته باشد، باز هم بهتر است یک رمز قوی تنظیم کنید.
اگر اعتبارسنجی رمز را فعال کرده باشید، قدرت رمز به شما نمایش داده میشود و از شما میپرسد آیا میخواهید آن را تایید کنید یا نه؟ اگر مورد تایید است، Y را بزنید.
Output Estimated strength of the password: 100 Do you wish to continue with the password provided?(Press y|Y for Yes, any other key for No) : y
در مراحل بعدی نیز برای تمام پرسشها Y بزنید و Enter کنید تا کاربران ناشناس حذف شوند، دیتابیس تست پاک شود، دسترسیهای غیرضروری غیرفعال شود و تنظیمات امنیتی اعمال شوند. در پایان، برای اطمینان از صحت نصب، وارد کنسول MySQL شوید:
sudo mysql Output Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 10 Server version: 8.0.28-0ubuntu4 (Ubuntu) Copyright (c) 2000, 2022, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql>
اگر همه چیز درست باشد، وارد محیط MySQL میشوید. برای خروج هم کد زیر را بنویسید:
exit
احتمالا متوجه میشوید که بدون وارد کردن رمز وارد شدید. دلیلش این است که در اوبونتو بهصورت پیشفرض ورود کاربر root دیتابیس از طریق auth_socket انجام میشود و نه رمزعبور. این موضوع نه تنها مشکل امنیتی نیست، بلکه دسترسی را محدودتر و امنتر میکند؛ چون فقط کاربران دارای دسترسی sudo میتوانند وارد شوند. البته این حساب برای اپلیکیشنهای PHP استفاده نمیشود و بهتر است برای هر دیتابیس یک کاربر مجزا با سطح دسترسی محدود بسازید.
نکته:
برخی نسخههای قدیمیتر کتابخانه PHP برای MySQL، از روش احراز هویت جدید MySQL 8 پشتیبانی نمیکنند. در این صورت هنگام ساخت کاربر باید از mysql_native_password استفاده کنید (که در گام ششم توضیح داده میشود).
در این مرحله MySQL با موفقیت نصب و ایمنسازی شده است. حالا میتوانید سراغ PHP بروید که آخرین بخش LEMP است.
۳. نصب PHP
حالا نوبت نصب PHP است تا بتواند کدها را پردازش کرده و محتوای پویا تولید کند. از آنجایی که Nginx برخلاف Apache خودش بهطور مستقیم PHP را اجرا نمیکند، برای پردازش درخواستهای PHP به یک سرویس خارجی نیاز داریم.
در اینجا از PHP-FPM (مخفف FastCGI Process Manager) استفاده میکنیم. این سرویس با عملکرد بهینهتر و امکانات امنیتی بهتر، باعث میشود وبسایتهای PHPمحور سریعتر و پایدارتر اجرا شوند. برای این منظور باید بسته php-fpm را برای پردازش درخواستهای PHP و بسته php-mysql را برای برقراری ارتباط PHP با MySQL نصب کنیم. بستههای اصلی PHP بهصورت خودکار همراه با این موارد نصب خواهند شد.
برای نصب PHP 8.1-FPM و افزونه MySQL دستور زیر را اجرا کنید:
sudo apt install php8.1-fpm php-mysql
پس از نمایش پیام تایید، کلید Y و سپس ENTER را بزنید تا نصب انجام شود. برای اطمینان از اجرا شدن PHP-FPM وضعیت سرویس را بررسی کنید:
sudo systemctl status php8.1-fpm
در صورت اجرای صحیح، باید وضعیت Active را مشاهده کنید:
php8.1-fpm.service - The PHP 8.1 FastCGI Process Manager Loaded: loaded Active: active (running)
همچنین میتوانید نسخه PHP نصبشده را بررسی کنید:
php -v
خروجی مشابه زیر خواهد بود:
Output PHP 8.1.x (cli) (built: ...) Copyright (c) The PHP Group Zend Engine v4.1.x
در ادامه باید Nginx را طوری تنظیم کنیم که از PHP-FPM برای پردازش فایلهای PHP استفاده کند.
۴. تنظیم Nginx برای استفاده از پردازشگر PHP
بلاکهای سرور Nginx (مشابه Virtual Host در Apache) را بسازید تا تنظیمات هر سایت را جدا نگه دارید و بتوانید چند دامنه را روی یک سرور میزبانی کنید. در این راهنما از your_domain بهعنوان دامنه نمونه استفاده شده است.
در اوبونتو 22.04، Nginx بهصورت پیشفرض یک بلاک سرور فعال دارد که فایلها را از مسیر /var/www/html سرو میکند. اگر قصد میزبانی چند سایت دارید، یک ساختار پوشه جدید داخل /var/www برای دامنه خود بسازید و /var/www/html را بهعنوان پیشفرض نگه دارید.
دایرکتوری ریشه وب دامنه را ایجاد کنید:
sudo mkdir /var/www/your_domain
سپس مالکیت پوشه را به کاربر فعلی دهید:
sudo chown -R $USER:$USER /var/www/your_domain
حالا یک فایل کانفیگ جدید در مسیر sites-available بسازید:
sudo nano /etc/nginx/sites-available/your_domain
محتوای زیر را داخل آن قرار دهید:
server {
listen 80;
server_name your_domain www.your_domain;
root /var/www/your_domain;
index index.html index.htm index.php;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
کار هر یک از این دستورها و بلاکهای location به شرح زیر است:
- listen → مشخص میکند Nginx روی کدام پورت گوش دهد (اینجا پورت 80 یعنی HTTP).
- root → مسیر داکیومنت روت سایت.
- index → ترتیب اولویت فایلهای index (بهطور معمول HTML قبل از PHP برای صفحات موقت).
- server_name → دامنهها یا IPهایی که این بلاک باید پاسخ دهد.
- location / → بررسی میکند آیا فایل/مسیر وجود دارد، در غیر این صورت 404 میدهد.
- location ~ .php$ → پردازش فایلهای PHP از طریق PHP-FPM.
- location ~ /.ht → جلوگیری از دسترسی به فایلهای .htaccess چون Nginx آنها را پردازش نمیکند.
بعد از اتمام ویرایش، فایل را ذخیره کرده و ببندید. اگر از ویرایشگر nano استفاده میکنید، با فشردن CTRL+X، سپس Y و ENTER تغییرات را تایید کنید.
کانفیگ خود را با ایجاد لینک به فایل تنظیمات از دایرکتوری sites-enabled در Nginx فعال کنید:
sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/
کانفیگ پیشفرض را غیرفعال کنید: (در صورت نیاز میتوانید دوباره لینک پیشفرض را برگردانید.)
sudo unlink /etc/nginx/sites-enabled/default
این به Nginx میگوید که در دفعه بعدی که بارگذاری شد، از این کانفیگ استفاده کند. برای بررسی خطاهای نگارشی فایل کانفیگ، دستور زیر را اجرا کنید:
sudo nginx -t
اگر خطایی گزارش شد، قبل از ادامه کار به فایل کانفیگ خود برگردید و محتویات آن را بررسی کنید.
وقتی آماده بودید، Nginx را مجدداً بارگذاری کنید تا تغییرات اعمال شوند:
sudo systemctl reload nginx
وبسایت جدید شما اکنون فعال است، اما دایرکتوری ریشه وب /var/www/your_domain هنوز خالی است. یک فایل index.html در این مسیر ایجاد کنید تا مطمئن شوید بلاک سرور جدید شما به درستی کار میکند.
nano /var/www/your_domain/index.html
محتوای زیر را در فایل قرار دهید:
<html> <head> <title>your_domain website</title> </head> <body> <h1>Hello World!</h1> <p>This is the landing page of <strong>your_domain</strong>.</p> </body> </html>
حالا در مرورگر آدرس دامنه یا IP سرور را مطابق http://server_domain_or_IP باز کنید.
اگر صفحه Hello World را دیدید یعنی بلاک سرور Nginx درست کار میکند.
نکته:
وقتی index.php اضافه کردید، حتما index.html را حذف یا تغییر نام دهید؛ چون Nginx بهصورت پیشفرض HTML را نمایش میدهد و PHP لود نمیشود.
در این مرحله LEMP شما آماده است. مرحله بعد تست PHP است تا مطمئن شوید Nginx فایلهای PHP را اجرا میکند.
۵. تست PHP با Nginx
در این مرحله، استک LEMP شما باید به طور کامل آماده باشد. حالا میتوانید تست کنید که Nginx قادر است فایلهای .php را به درستی به پردازشگر PHP تحویل دهد.
برای این کار، یک فایل تست PHP داخل روت سایت ایجاد کنید. یک فایل جدید به نام info.php در مسیر داکیومنت روت بسازید:
nano /var/www/your_domain/info.php
محتوای زیر را داخل فایل قرار دهید. این یک کد PHP معتبر است که اطلاعات سرور شما را نمایش میدهد:
<?php phpinfo();
بعد از ذخیره و بستن فایل، در مرورگر آدرس دامنه یا IP سرور خود (http://server_domain_or_IP/info.php) را به همراه /info.php باز کنید.
باید صفحهای شامل اطلاعات کامل PHP سرور خود ببینید.

پس از بررسی اطلاعات مورد نیاز، بهتر است این فایل را حذف کنید چون شامل اطلاعات حساس درباره محیط PHP و سرور اوبونتوی شما است. برای حذف فایل از دستور زیر استفاده کنید:
sudo rm /var/www/your_domain/info.php
هر زمان لازم شد دوباره میتوانید این فایل را ایجاد کنید.
۶. تست اتصال پایگاه داده از طریق PHP (اختیاری)
اگر میخواهید بررسی کنید که PHP قادر است به MySQL متصل شود و کوئری اجرا کند، میتوانید یک دیتابیس تست بسازید، دادهی آزمایشی اضافه کنید و سپس از طریق PHP آن را بخوانید.
نکته: برخی نسخههای قدیمی کتابخانه MySQL PHP از روش احراز هویت caching_sha2_authentication در MySQL 8 پشتیبانی نمیکنند، بنابراین ممکن است مجبور شوید کاربران را با mysql_native_password بسازید.
در این راهنما یک دیتابیس با نام example_database و یک کاربر با نام example_user میسازیم (شما میتوانید نامها را تغییر دهید).
ابتدا وارد کنسول MySQL شوید:
sudo mysql
برای ایجاد یک دیتابیس جدید، دستور زیر را در کنسول MySQL خود اجرا کنید:
mysq> CREATE DATABASE example_database;
ساخت کاربر جدید با روش احراز هویت mysql_native_password و تعیین پسورد (پسورد خودتان را جایگزین کنید):
mysq> CREATE USER 'example_user'@'%' IDENTIFIED WITH mysql_native_password BY 'password';
دادن سطح دسترسی کامل به این دیتابیس:
mysq> GRANT ALL ON example_database.* TO 'example_user'@'%';
این دستور به کاربر example_user دسترسی کامل روی دیتابیس example_database میدهد، در حالی که از ایجاد یا تغییر سایر دیتابیسهای سرور جلوگیری میکند. حالا برای خروج از محیط MySQL از دستور زیر استفاده کنید:
mysq> exit
برای بررسی اینکه کاربر جدید دسترسیهای لازم را دارد یا خیر، دوباره وارد کنسول MySQL شوید، اما این بار با استفاده از نام کاربری و رمز عبور مخصوص همان کاربر جدید. توجه کنید که گزینه -p باعث میشود هنگام ورود، رمز عبور کاربر example_user از شما درخواست شود.
$ mysql -u example_user -p
پس از ورود به کنسول MySQL، با کد زیر مطمئن شوید که به دیتابیس دسترسی دارید:
mysq> SHOW DATABASES;
سپس خروجی باید چیزی شبیه به این باشد:
Output +--------------------+ | Database | +--------------------+ | example_database | | information_schema | +--------------------+ 2 rows in set (0.000 sec) یک جدول تست به نام todo_list بسازید: mysq> CREATE TABLE example_database.todo_list ( mysq> item_id INT AUTO_INCREMENT, mysq> content VARCHAR(255), mysq> PRIMARY KEY(item_id) mysq> );
چند ردیف نمونه در جدول تستی وارد کنید. میتوانید دستور زیر را چند بار با مقادیر متفاوت تکرار کنید:
mysq> INSERT INTO example_database.todo_list (content) VALUES ("My first important item");
برای اطمینان از اینکه دادهها با موفقیت در جدول شما ذخیره شدهاند، دستور زیر را اجرا کنید:
mysq> SELECT * FROM example_database.todo_list;
سپس خروجی باید چیزی شبیه به دستور زیر باشد:
Output +---------+--------------------------+ | item_id | content | +---------+--------------------------+ | 1 | My first important item | | 2 | My second important item | | 3 | My third important item | | 4 | and this one more thing | +---------+--------------------------+ 4 rows in set (0.000 sec)
پس از اطمینان از ثبت صحیح دادهها، خارج شوید:
mysq> exit
حالا یک فایل PHP برای اتصال به دیتابیس و نمایش دادهها ایجاد کنید:
$ nano /var/www/your_domain/todo_list.php
دستور زیر را وارد کنید:
<?php
$user = "example_user";
$password = "password";
$database = "example_database";
$table = "todo_list";
try {
$db = new PDO("mysql:host=localhost;dbname=$database", $user, $password);
echo "<h2>TODO</h2><ol>";
foreach($db->query("SELECT content FROM $table") as $row) {
echo "<li>" . $row['content'] . "</li>";
}
echo "</ol>";
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
فایل را ذخیره کنید و ببندید. حالا در مرورگر آدرس زیر را باز کنید:
- http://server_domain_or_IP/todo_list.php
اگر لیست موارد وارد شده را دیدید، یعنی PHP شما به درستی به MySQL متصل شده و آماده استفاده است.
رفع مشکلات رایج
خطای 502 Bad Gateway
رایجترین مشکل در استک LEMP زمانی رخ میدهد که Nginx نتواند با PHP-FPM ارتباط برقرار کند.
مراحل بررسی و رفع مشکل:
- بررسی وضعیت PHP-FPM:
sudo systemctl status php8.1-fpm
- بررسی مسیر سوکت PHP-FPM:
ls -la /run/php/
خروجی مورد انتظار باید فایل php8.1-fpm.sock را نشان دهد.
راهحلهای رایج برای رفع مشکل:
ریاستارت کردن PHP-FPM:
sudo systemctl restart php8.1-fpm
مطمئن شوید مسیر سوکت در Server Block Nginx، با مسیر واقعی سوکت PHP-FPM یکی است.
دسترسی فایل را بررسی کنید تا یوزر Nginx (یعنی www-data) اجازه دسترسی داشته باشد:
sudo chown www-data:www-data /run/php/php8.1-fpm.sock
مشکل دسترسی
اگر با خطاهای مربوط به مجوز دسترسی مواجه شدید، مجوزهای دایرکتوری وب را اصلاح کنید:
sudo chown -R www-data:www-data /var/www/your_domain sudo chmod -R 755 /var/www/your_domain
مشکل اتصال MySQL
اگر با مشکل اتصال به MySQL مواجه شدید، میتوانید رمز کاربر root را ریست کنید:
sudo mysql ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'new_password'; FLUSH PRIVILEGES; EXIT;
اجرا نشدن PHP
اگر به این مشکل برخوردید که PHP پردازش نمیشود، مراحل زیر را برای بررسی و رفع آن دنبال کنید.
بررسی ماژولهای PHP:
php -m | grep -E 'mysql|fpm'
بررسی پیکربندی PHP-FPM و Nginx:
sudo nginx -t sudo php-fpm8.1 -t رفع خطای 404:
اطمینان حاصل کنید که فایل index.php در دستور index در تنظیمات Nginx ذکر شده است.
بررسی کنید فایل مورد نظر در مسیر وب وجود دارد:
ls -la /var/www/your_domain/
مشاهده لاگ خطاهای Nginx برای جزئیات بیشتر:
sudo tail -f /var/log/nginx/error.log
جمعبندی
در این مقاله نحوه نصب و راهاندازی LEMP Stack روی سرور اوبونتو را مرور کردیم. با دنبال کردن این مراحل، اکنون میتوانید وبسایتها و برنامههای PHP را با بهرهگیری از Nginx بهعنوان وبسرور، MySQL برای ذخیره و مدیریت دادهها و PHP-FPM برای پردازش محتوای پویا اجرا کنید.