برای اجرای سایتها و برنامههای PHP روی Nginx، نصب خود PHP بهتنهایی کافی نیست. برخلاف Apache که میتواند از ماژولهایی مانند mod_php استفاده کند، Nginx موتور داخلی برای اجرای کد PHP ندارد. به همین دلیل، درخواستهای مربوط به فایلهای PHP باید از طریق پروتکل FastCGI به سرویس PHP-FPM ارسال شوند.
پیکربندی PHP-FPM با Nginx یکی از مهمترین مراحل راهاندازی یک سرور LEMP است. اگر مسیر Socket، سطح دسترسی فایلها، تنظیمات Pool یا بخش fastcgi_pass اشتباه باشد، ممکن است سایت بهجای اجرا فایل PHP را دانلود کند، با خطای ۵۰۲ Bad Gateway روبهرو شود یا مصرف RAM و CPU سرور بهشدت افزایش پیدا کند.
در این راهنما، نصب PHP-FPM روی Ubuntu، ساخت Pool اختصاصی برای هر سایت، اتصال Nginx به PHP-FPM، استفاده از Unix Socket یا TCP، تنظیم سطح دسترسی، تست اجرای PHP، مانیتورینگ Workerها، بهینهسازی Process Manager و رفع خطاهای رایج را مرحلهبهمرحله بررسی میکنیم.
سطح مقاله: متوسط | مناسب برای: مدیران سرور، کاربران VPS، توسعهدهندگان PHP، مدیران سایت وردپرسی، متخصصان DevOps و افرادی که از Nginx بهعنوان وبسرور استفاده میکنند.
فهرست مطالب
- PHP-FPM چیست؟
- Nginx و PHP-FPM چگونه با هم کار میکنند؟
- نسخه PHP-FPM در Ubuntu ۲۲.۰۴، ۲۴.۰۴ و ۲۶.۰۴
- پیشنیازهای نصب
- نصب Nginx و PHP-FPM
- بررسی سرویس و Socket مربوط به PHP-FPM
- ساخت مسیر سایت و کاربر اختصاصی
- ساخت PHP-FPM Pool اختصاصی
- پیکربندی Server Block در Nginx
- تست تنظیمات Nginx و PHP-FPM
- تفاوت Unix Socket و TCP در FastCGI
- امنسازی PHP-FPM و Nginx
- تنظیم Process Manager در PHP-FPM
- محاسبه pm.max_children
- فعالسازی صفحه وضعیت PHP-FPM
- فعالسازی Slow Log در PHP-FPM
- ساخت Pool جداگانه برای چند سایت
- تنظیم PHP-FPM برای وردپرس
- رفع خطای ۵۰۲ Bad Gateway
- خطاهای رایج دیگر
- چکلیست امنیت و عملکرد
- سوالات متداول
- جمعبندی
PHP-FPM چیست؟
PHP-FPM مخفف PHP FastCGI Process Manager است. این سرویس مجموعهای از پردازشهای PHP را مدیریت میکند و درخواستهای دریافتشده از وبسرور را اجرا میکند.
PHP-FPM معمولاً شامل این اجزا است:
- Master Process: پردازش اصلی که Poolها و Workerها را مدیریت میکند.
- Worker Process: پردازشهایی که فایلهای PHP را اجرا میکنند.
- Pool: مجموعهای از Workerها با کاربر، Socket و محدودیت منابع مشخص.
- Unix Socket یا TCP Port: مسیری که Nginx از طریق آن درخواست را به PHP-FPM تحویل میدهد.
برای مثال، وقتی کاربر صفحه index.php را باز میکند، Nginx درخواست را دریافت میکند؛ اما اجرای فایل را به PHP-FPM میسپارد. PHP-FPM کد را اجرا میکند، خروجی HTML را به Nginx برمیگرداند و Nginx پاسخ نهایی را برای مرورگر ارسال میکند.
Nginx و PHP-FPM چگونه با هم کار میکنند؟
فرایند اجرای یک درخواست PHP معمولاً به این شکل است:
- مرورگر آدرس
https://example.com/index.phpرا درخواست میکند. - Nginx درخواست را دریافت و Server Block مربوط به دامنه را انتخاب میکند.
- بخش
location ~ \.php$تشخیص میدهد که درخواست مربوط به PHP است. - Nginx اطلاعات درخواست را با FastCGI به PHP-FPM ارسال میکند.
- PHP-FPM یکی از Workerهای آزاد را برای اجرای فایل انتخاب میکند.
- خروجی اجرای PHP به Nginx بازگردانده میشود.
- Nginx پاسخ نهایی را برای کاربر ارسال میکند.
در این ساختار، Nginx معمولاً فایلهای استاتیک مانند تصویر، CSS و JavaScript را مستقیماً ارائه میکند و فقط درخواستهای PHP را به PHP-FPM میفرستد. این تفکیک میتواند کارایی و کنترل منابع سرور را بهبود دهد.
نسخه PHP-FPM در Ubuntu ۲۲.۰۴، ۲۴.۰۴ و ۲۶.۰۴
مسیر سرویس، پوشه Pool و Socket به نسخه PHP بستگی دارد. بنابراین قبل از ادامه، نسخه Ubuntu و PHP را بررسی کنید:
lsb_release -rs
php -v| نسخه Ubuntu | نسخه پیشفرض PHP | نام سرویس | Socket پیشفرض |
|---|---|---|---|
| Ubuntu 22.04 | PHP 8.1 | php8.1-fpm | /run/php/php8.1-fpm.sock |
| Ubuntu 24.04 | PHP 8.3 | php8.3-fpm | /run/php/php8.3-fpm.sock |
| Ubuntu 26.04 | PHP 8.5 | php8.5-fpm | /run/php/php8.5-fpm.sock |
نکته مهم: جدول بالا مربوط به مخازن پیشفرض Ubuntu است. اگر PHP را از Repository دیگری نصب کرده باشید، ممکن است نسخه، مسیر و نام سرویس متفاوت باشد.
برای مشاهده Socketهای واقعی موجود روی سرور از این دستور استفاده کنید:
ls -lah /run/php/پیشنیازهای نصب
برای اجرای مراحل مقاله به موارد زیر نیاز دارید:
- یک سرور Ubuntu ۲۲.۰۴، ۲۴.۰۴ یا ۲۶.۰۴
- دسترسی SSH
- کاربر دارای دسترسی sudo
- یک دامنه متصل به IP سرور
- پورتهای ۸۰ و ۴۴۳ باز در فایروال
- آشنایی پایه با دستورات لینوکس
این ساختار برای اجرا روی سرور مجازی ایران، سرور مجازی آلمان یا سرور اختصاصی مناسب است. در هاست اشتراکی معمولاً دسترسی لازم برای ویرایش Poolهای PHP-FPM در اختیار کاربر قرار ندارد.
نصب Nginx و PHP-FPM
ابتدا فهرست پکیجها را بهروزرسانی کنید:
sudo apt updateسپس Nginx را نصب کنید:
sudo apt install nginx -yبرای نصب PHP-FPM باید نسخه متناسب با سیستمعامل خود را انتخاب کنید.
Ubuntu 22.04
sudo apt install php8.1-fpm php8.1-cli -yUbuntu 24.04
sudo apt install php8.3-fpm php8.3-cli -yUbuntu 26.04
sudo apt install php8.5-fpm php8.5-cli -yدر Ubuntu ۲۴.۰۴ و ۲۶.۰۴ میتوانید از Meta Package زیر نیز استفاده کنید:
sudo apt install php-fpm php-cli -yبرای سایتهای معمول PHP و وردپرس، افزونههای پرکاربرد را نیز نصب کنید. در مثال زیر عبارت 8.3 را با نسخه PHP خود جایگزین کنید:
sudo apt install \
php8.3-mysql \
php8.3-curl \
php8.3-gd \
php8.3-mbstring \
php8.3-xml \
php8.3-zip \
php8.3-intl \
php8.3-bcmath \
php8.3-opcache -yبررسی سرویس و Socket مربوط به PHP-FPM
سرویسهای Nginx و PHP-FPM را فعال و اجرا کنید:
sudo systemctl enable --now nginx
sudo systemctl enable --now php8.3-fpmوضعیت PHP-FPM:
sudo systemctl status php8.3-fpmباید وضعیت زیر را مشاهده کنید:
active (running)برای مشاهده Socket:
ls -l /run/php/php8.3-fpm.sockهمچنین میتوانید فایل Pool پیشفرض را بررسی کنید:
grep -E '^listen\s*=' /etc/php/8.3/fpm/pool.d/www.confخروجی معمولاً مشابه این است:
listen = /run/php/php8.3-fpm.sockساخت مسیر سایت و کاربر اختصاصی
برای امنیت بهتر، مخصوصاً وقتی چند سایت روی یک سرور میزبانی میشوند، بهتر است هر سایت کاربر Unix و PHP-FPM Pool اختصاصی داشته باشد.
ابتدا گروه و کاربر را ایجاد کنید:
sudo groupadd example_user
sudo useradd \
-g example_user \
-d /var/www/example.com \
-s /usr/sbin/nologin \
example_userمسیر سایت را بسازید:
sudo mkdir -p /var/www/example.com/publicمالکیت مسیر را تنظیم کنید:
sudo chown -R example_user:example_user /var/www/example.comسطح دسترسی پیشنهادی اولیه:
sudo find /var/www/example.com -type d -exec chmod 755 {} \;
sudo find /var/www/example.com -type f -exec chmod 644 {} \;داشتن Pool جداگانه باعث میشود فایلها و Workerهای هر سایت از سایتهای دیگر جدا شوند و بتوانید برای هر دامنه محدودیت منابع مستقل تعریف کنید.
ساخت PHP-FPM Pool اختصاصی
فایل Poolها در مسیر زیر قرار دارند:
/etc/php/VERSION/fpm/pool.d/برای PHP ۸.۳ یک فایل جدید بسازید:
sudo nano /etc/php/8.3/fpm/pool.d/example.com.confمحتوای زیر را وارد کنید:
[example_com]
user = example_user
group = example_user
listen = /run/php/php8.3-fpm-example.com.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
pm = dynamic
pm.max_children = 10
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 4
pm.max_requests = 500
request_terminate_timeout = 120s
request_slowlog_timeout = 5s
slowlog = /var/log/php8.3-fpm-example.com-slow.log
php_admin_value[error_log] = /var/log/php8.3-fpm-example.com-error.log
php_admin_flag[log_errors] = on
php_admin_value[upload_max_filesize] = 64M
php_admin_value[post_max_size] = 64M
php_admin_value[memory_limit] = 256M
php_admin_value[max_execution_time] = 120
clear_env = yes
security.limit_extensions = .phpتوضیح تنظیمات مهم Pool
| گزینه | کاربرد |
|---|---|
[example_com] | نام منحصربهفرد Pool |
user و group | کاربری که Workerهای PHP با آن اجرا میشوند |
listen | مسیر Socket یا آدرس TCP برای دریافت درخواستها |
listen.owner | مالک Socket؛ باید برای کاربر Nginx قابل دسترسی باشد |
pm | روش مدیریت Workerها |
pm.max_children | حداکثر تعداد درخواستهای PHP همزمان |
pm.max_requests | تعداد درخواست پیش از بازیابی هر Worker |
request_terminate_timeout | حداکثر زمان اجرای یک درخواست |
slowlog | مسیر ثبت درخواستهای PHP کند |
بعد از ذخیره فایل، صحت تنظیمات PHP-FPM را بررسی کنید:
sudo php-fpm8.3 -tدر صورت نبود خطا، سرویس را Reload کنید:
sudo systemctl reload php8.3-fpmوجود Socket جدید را بررسی کنید:
ls -l /run/php/php8.3-fpm-example.com.sockپیکربندی Server Block در Nginx
یک فایل جدید برای دامنه بسازید:
sudo nano /etc/nginx/sites-available/example.comپیکربندی زیر را وارد کنید:
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com/public;
index index.php index.html index.htm;
access_log /var/log/nginx/example.com-access.log;
error_log /var/log/nginx/example.com-error.log;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
try_files $uri =404;
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm-example.com.sock;
fastcgi_read_timeout 120;
fastcgi_connect_timeout 30;
fastcgi_send_timeout 120;
}
location ~ /\.(?!well-known).* {
deny all;
}
location ~* \.(?:css|js|jpg|jpeg|gif|png|svg|webp|ico|woff|woff2)$ {
expires 30d;
access_log off;
log_not_found off;
}
}نقش SCRIPT_FILENAME
PHP-FPM باید مسیر واقعی فایل PHP روی دیسک را دریافت کند. در Ubuntu، فایل زیر معمولاً این پارامترها را تنظیم میکند:
include snippets/fastcgi-php.conf;اگر این Snippet روی سیستم شما وجود ندارد، میتوانید پارامترهای ضروری را مستقیم بنویسید:
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $document_root;استفاده از try_files $uri =404; پیش از ارسال درخواست به PHP-FPM باعث میشود فقط فایل PHP واقعاً موجود اجرا شود.
فعالسازی سایت
sudo ln -s \
/etc/nginx/sites-available/example.com \
/etc/nginx/sites-enabled/example.comدر صورت نیاز، سایت پیشفرض را غیرفعال کنید:
sudo rm -f /etc/nginx/sites-enabled/defaultتنظیمات Nginx را تست کنید:
sudo nginx -tاگر خروجی موفق بود:
sudo systemctl reload nginxتست تنظیمات Nginx و PHP-FPM
یک فایل تست PHP بسازید:
echo '<?php phpinfo(); ?>' | \
sudo tee /var/www/example.com/public/info.phpمالکیت آن را اصلاح کنید:
sudo chown example_user:example_user \
/var/www/example.com/public/info.phpحالا آدرس زیر را در مرورگر باز کنید:
http://example.com/info.phpدر صفحه PHP Info این موارد را بررسی کنید:
- Server API باید برابر
FPM/FastCGIباشد. - نسخه PHP باید همان نسخه موردنظر باشد.
- مقادیر
memory_limitوupload_max_filesizeباید با Pool هماهنگ باشند. - فایل php.ini بارگذاریشده باید مربوط به مسیر FPM باشد.
پس از تست، فایل PHP Info را فوراً حذف کنید؛ چون اطلاعات حساس سرور را نمایش میدهد:
sudo rm /var/www/example.com/public/info.phpبرای تست از خط فرمان نیز میتوانید استفاده کنید:
curl -I http://example.comتفاوت Unix Socket و TCP در FastCGI
Nginx میتواند از دو روش به PHP-FPM متصل شود:
اتصال با Unix Socket
fastcgi_pass unix:/run/php/php8.3-fpm.sock;Unix Socket برای زمانی مناسب است که Nginx و PHP-FPM روی یک سرور اجرا میشوند.
مزایا:
- عدم نیاز به باز کردن پورت شبکه
- کنترل دسترسی با مالک و Permission فایل Socket
- پیادهسازی ساده برای یک سرور
اتصال با TCP
در فایل Pool:
listen = 127.0.0.1:9000در Nginx:
fastcgi_pass 127.0.0.1:9000;TCP معمولاً در این سناریوها استفاده میشود:
- Nginx و PHP-FPM در کانتینرهای جدا اجرا میشوند.
- PHP-FPM روی سرور دیگری قرار دارد.
- ارتباط از طریق شبکه Docker یا Kubernetes انجام میشود.
- Load Balancing بین چند PHP-FPM Backend لازم است.
اگر TCP استفاده میکنید، PHP-FPM را بدون فایروال و احراز امنیتی روی اینترنت عمومی باز نکنید. بهتر است سرویس فقط روی localhost، شبکه خصوصی یا VPN قابل دسترسی باشد.
امنسازی PHP-FPM و Nginx
اجرای هر سایت با کاربر مستقل
اجرای همه سایتها با کاربر مشترک www-data باعث میشود در صورت نفوذ به یک سایت، دسترسی به فایلهای سایتهای دیگر سادهتر شود. برای سرورهای چندسایته، Pool جدا با کاربر اختصاصی توصیه میشود.
محدود کردن پسوندهای قابل اجرا
در فایل Pool:
security.limit_extensions = .phpبا این تنظیم، PHP-FPM فقط فایلهای دارای پسوند PHP را اجرا میکند.
جلوگیری از اجرای PHP در پوشه Upload
برای وردپرس میتوانید اجرای PHP در مسیر Upload را ببندید:
location ~* /wp-content/uploads/.*\.php$ {
deny all;
}مخفی کردن فایلهای حساس
location ~ /\.(?!well-known).* {
deny all;
}برای وردپرس:
location = /wp-config.php {
deny all;
}
location ~* /(readme\.html|license\.txt)$ {
deny all;
}غیرفعال کردن نمایش خطا در Production
در Pool یا php.ini:
php_admin_flag[display_errors] = off
php_admin_flag[log_errors] = onنمایش خطا به کاربران ممکن است مسیر فایلها، Queryها و اطلاعات داخلی برنامه را افشا کند.
فعالسازی HTTPS
بعد از اطمینان از اجرای صحیح سایت، گواهی SSL نصب کنید و تمام درخواستهای HTTP را به HTTPS منتقل کنید.
تنظیم Process Manager در PHP-FPM
PHP-FPM سه روش اصلی برای مدیریت Workerها دارد:
حالت static
pm = static
pm.max_children = 10همیشه تعداد ثابتی Worker فعال است. این حالت برای ترافیک پایدار و سرور دارای RAM کافی قابل استفاده است، اما در زمان کمترافیک نیز حافظه مصرف میکند.
حالت dynamic
pm = dynamic
pm.max_children = 10
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 4PHP-FPM تعداد Workerها را متناسب با ترافیک کم و زیاد میکند. این حالت برای بسیاری از سایتهای Production انتخاب مناسبی است.
حالت ondemand
pm = ondemand
pm.max_children = 10
pm.process_idle_timeout = 10sWorkerها فقط هنگام دریافت درخواست ایجاد میشوند و پس از بیکار ماندن متوقف میشوند. این حالت برای سایتهای کمترافیک یا سرورهای دارای تعداد زیاد سایت مناسب است، اما ممکن است اولین درخواست کمی تأخیر داشته باشد.
چطور pm.max_children را محاسبه کنیم؟
هر PHP-FPM Worker مقداری RAM مصرف میکند. اگر تعداد Workerها بیش از ظرفیت سرور باشد، سیستم وارد Swap میشود یا سرویسها توسط OOM Killer متوقف میشوند.
ابتدا مصرف حافظه Workerهای PHP را بررسی کنید:
ps --no-headers -o rss,cmd -C php-fpm8.3یا:
ps -ylC php-fpm8.3 --sort:rssبرای محاسبه متوسط مصرف Workerها:
ps --no-headers -o rss -C php-fpm8.3 | \
awk '{sum+=$1; count++} END {
if (count > 0) print sum/count/1024 " MB"
}'فرمول تقریبی:
pm.max_children =
RAM قابل اختصاص به PHP-FPM ÷ متوسط RAM هر Workerمثال:
- RAM کل سرور: ۴ گیگابایت
- RAM رزروشده برای سیستم، Nginx و دیتابیس: ۲ گیگابایت
- RAM قابل اختصاص به PHP-FPM: ۲ گیگابایت
- مصرف متوسط هر Worker: ۸۰ مگابایت
2048 ÷ 80 = 25در این سناریو میتوان مقدار محافظهکارانهای مانند ۲۰ تا ۲۲ برای pm.max_children در نظر گرفت و سپس با مانیتورینگ واقعی آن را تنظیم کرد.
هشدار: مقدار زیاد pm.max_children الزاماً سایت را سریعتر نمیکند. اگر CPU، دیتابیس یا RAM ظرفیت کافی نداشته باشد، افزایش Workerها میتواند سرور را کندتر کند.
فعالسازی صفحه وضعیت PHP-FPM
در فایل Pool این گزینه را اضافه کنید:
pm.status_path = /fpm-statusدر Server Block مربوط به Nginx:
location = /fpm-status {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php8.3-fpm-example.com.sock;
allow 127.0.0.1;
allow YOUR_MONITORING_IP;
deny all;
access_log off;
}پس از Reload سرویسها:
sudo systemctl reload php8.3-fpm
sudo systemctl reload nginxاز داخل سرور تست کنید:
curl http://127.0.0.1/fpm-statusاطلاعات صفحه Status شامل موارد زیر است:
- تعداد Workerهای فعال و بیکار
- تعداد کل درخواستهای پردازششده
- طول صف درخواستها
- بیشترین تعداد Workerهای فعال
- تعداد دفعات رسیدن به سقف Workerها
این صفحه نباید بدون محدودیت IP در دسترس اینترنت قرار گیرد.
فعالسازی Slow Log در PHP-FPM
Slow Log برای پیدا کردن اسکریپتهای کند، افزونههای سنگین، Queryهای طولانی و درخواستهایی که Workerها را مشغول نگه میدارند کاربرد دارد.
در فایل Pool:
request_slowlog_timeout = 5s
slowlog = /var/log/php8.3-fpm-example.com-slow.logبعد از Reload، درخواستهایی که بیش از پنج ثانیه طول بکشند در فایل Slow Log ثبت میشوند:
sudo tail -f /var/log/php8.3-fpm-example.com-slow.logلاگ خطا:
sudo tail -f /var/log/php8.3-fpm-example.com-error.logساخت Pool جداگانه برای چند سایت
فرض کنید سه سایت روی یک سرور دارید:
site1.com
site2.com
shop.example.comبرای هر سایت میتوان یک کاربر، Pool و Socket مستقل ساخت:
/run/php/php8.3-fpm-site1.sock
/run/php/php8.3-fpm-site2.sock
/run/php/php8.3-fpm-shop.sockمزایای این ساختار:
- جداسازی امنیتی فایلها و پردازشها
- تعیین memory_limit مستقل
- تعیین pm.max_children مستقل
- ثبت Error Log و Slow Log جداگانه
- امکان اجرای سایتها با نسخههای متفاوت PHP
- جلوگیری از مصرف تمام Workerها توسط یک سایت پرترافیک
در Server Block هر سایت، فقط Socket همان Pool را قرار دهید:
fastcgi_pass unix:/run/php/php8.3-fpm-site1.sock;تنظیم PHP-FPM و Nginx برای وردپرس
برای وردپرس، بخش اصلی Nginx معمولاً به این شکل است:
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
try_files $uri =404;
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm-wordpress.sock;
}
location ~* /wp-content/uploads/.*\.php$ {
deny all;
}افزونههای موردنیاز وردپرس و WooCommerce معمولاً شامل این موارد هستند:
php-mysql
php-curl
php-gd
php-mbstring
php-xml
php-zip
php-intl
php-bcmath
php-opcacheبرای سایتهای پرترافیک میتوان Redis Object Cache، FastCGI Cache یا Page Cache را نیز بررسی کرد. اگر مدیریت سرور و تنظیم PHP-FPM برایتان پیچیده است، استفاده از هاست وردپرس مدیریتشده میتواند نیاز به تنظیم دستی Workerها و وبسرور را کاهش دهد.
رفع خطای ۵۰۲ Bad Gateway در Nginx و PHP-FPM
خطای ۵۰۲ معمولاً یعنی Nginx نتوانسته از PHP-FPM پاسخ معتبر دریافت کند.
مرحله اول: بررسی اجرای PHP-FPM
sudo systemctl status php8.3-fpmاگر سرویس متوقف است:
sudo systemctl restart php8.3-fpmمرحله دوم: تطبیق مسیر Socket
مسیر تعریفشده در Nginx را بررسی کنید:
grep -R "fastcgi_pass" /etc/nginx/sites-enabled/مسیر تعریفشده در PHP-FPM:
grep -R "^listen\s*=" /etc/php/8.3/fpm/pool.d/این دو مسیر باید دقیقاً یکسان باشند.
مرحله سوم: بررسی وجود Socket
ls -lah /run/php/اگر Socket وجود ندارد، احتمالاً Pool بارگذاری نشده یا فایل کانفیگ خطا دارد:
sudo php-fpm8.3 -t
sudo journalctl -u php8.3-fpm -n 100 --no-pagerمرحله چهارم: بررسی Permission مربوط به Socket
ls -l /run/php/php8.3-fpm-example.com.sockکاربر Nginx که معمولاً www-data است باید اجازه اتصال به Socket را داشته باشد:
listen.owner = www-data
listen.group = www-data
listen.mode = 0660مرحله پنجم: بررسی لاگ Nginx
sudo tail -f /var/log/nginx/example.com-error.logپیامهای رایج:
connect() to unix:/run/php/... failed
Permission denied
No such file or directory
Connection refused
upstream timed outمرحله ششم: بررسی Timeout
اگر اسکریپت واقعاً زمان زیادی نیاز دارد:
fastcgi_read_timeout 300;و در Pool:
request_terminate_timeout = 300sافزایش Timeout نباید جایگزین عیبیابی اسکریپت یا Query کند. ابتدا علت کندی را با Slow Log و لاگ دیتابیس بررسی کنید.
خطاهای رایج دیگر
فایل PHP بهجای اجرا دانلود میشود
این مشکل معمولاً یعنی بخش PHP در Server Block وجود ندارد یا فایل کانفیگ سایت فعال نشده است.
بررسی کنید این بخش وجود داشته باشد:
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}سپس:
sudo nginx -t
sudo systemctl reload nginxخطای File not found
علتهای رایج:
- مقدار
rootاشتباه است. - پارامتر
SCRIPT_FILENAMEدرست تنظیم نشده است. - فایل PHP در مسیر موردنظر وجود ندارد.
- Nginx و PHP-FPM مسیرهای متفاوتی را در کانتینر میبینند.
خطای Permission denied
مالکیت فایلها را بررسی کنید:
namei -l /var/www/example.com/public/index.phpاین دستور Permission تمام پوشههای مسیر را نشان میدهد.
بررسی مالکیت:
ls -lah /var/www/example.com/public/خطای pool seems busy
اگر در لاگ پیامهایی درباره Busy شدن Pool یا رسیدن به pm.max_children مشاهده میکنید، ممکن است:
- تعداد Workerها کم باشد.
- اسکریپتها یا Queryها کند باشند.
- ترافیک ناگهانی افزایش یافته باشد.
- رباتها یا حمله HTTP منابع را اشغال کرده باشند.
- سرویس خارجی باعث معطل ماندن درخواستها شده باشد.
قبل از افزایش Workerها، Slow Log، مصرف RAM، CPU، دیتابیس و Access Log را بررسی کنید.
مقدار php.ini تغییر نمیکند
PHP CLI و PHP-FPM فایلهای php.ini جداگانه دارند.
مسیر PHP CLI:
/etc/php/8.3/cli/php.iniمسیر PHP-FPM:
/etc/php/8.3/fpm/php.iniبعد از تغییر تنظیمات FPM:
sudo systemctl reload php8.3-fpmچکلیست امنیت و عملکرد PHP-FPM با Nginx
- نسخه واقعی PHP پیش از ویرایش مسیرها بررسی شده باشد.
- Nginx و PHP-FPM از Socket یا TCP یکسان استفاده کنند.
- برای هر سایت مهم Pool و کاربر جداگانه ساخته شود.
- Socket فقط برای کاربر لازم قابل دسترسی باشد.
security.limit_extensionsروی.phpتنظیم شود.- فایلهای PHP فقط در صورت وجود به PHP-FPM ارسال شوند.
- اجرای PHP در پوشه Upload مسدود شود.
- نمایش خطا در Production غیرفعال و ثبت لاگ فعال باشد.
- صفحه PHP Info بعد از تست حذف شود.
- صفحه FPM Status با IP محدود شود.
- Slow Log برای پیدا کردن درخواستهای کند فعال باشد.
pm.max_childrenبر اساس RAM واقعی محاسبه شود.- مقادیر Timeout بدون دلیل بیش از حد افزایش پیدا نکنند.
- PHP، Nginx و Ubuntu مرتب بهروزرسانی شوند.
- HTTPS و گواهی SSL معتبر فعال باشد.
- از فایلهای Nginx، Poolها و php.ini بکاپ گرفته شود.
سوالات متداول درباره PHP-FPM و Nginx
PHP-FPM چیست؟
PHP-FPM یک Process Manager برای PHP است که مجموعهای از Workerها را برای اجرای اسکریپتهای PHP مدیریت میکند و درخواستها را از طریق FastCGI دریافت میکند.
آیا Nginx بدون PHP-FPM میتواند PHP اجرا کند؟
خیر. Nginx موتور داخلی اجرای PHP ندارد و برای اجرای فایلهای PHP باید درخواست را به PHP-FPM یا یک FastCGI Handler دیگر ارسال کند.
fastcgi_pass چیست؟
دستور fastcgi_pass در Nginx مقصد ارسال درخواستهای FastCGI را مشخص میکند. مقصد میتواند Unix Socket یا یک IP و پورت TCP باشد.
Unix Socket بهتر است یا TCP؟
اگر Nginx و PHP-FPM روی یک سرور هستند، Unix Socket معمولاً انتخاب ساده و امنی است. اگر سرویسها روی کانتینر یا سرورهای جدا قرار دارند، TCP مناسبتر است.
علت خطای ۵۰۲ Bad Gateway چیست؟
رایجترین علتها توقف سرویس PHP-FPM، اشتباه بودن مسیر Socket، Permission نامناسب Socket، Crash کردن Workerها یا Timeout درخواست است.
چطور بفهمیم PHP-FPM در حال اجرا است؟
sudo systemctl status php8.3-fpmنام سرویس را با نسخه PHP نصبشده جایگزین کنید.
چطور مسیر Socket مربوط به PHP-FPM را پیدا کنیم؟
ls -lah /run/php/
grep -R "^listen\s*=" /etc/php/*/fpm/pool.d/Pool در PHP-FPM چیست؟
Pool مجموعهای از Workerهای PHP با کاربر، گروه، Socket، محدودیت حافظه و تنظیمات Process Manager مستقل است.
آیا برای هر سایت باید Pool جدا بسازیم؟
برای یک سایت ساده استفاده از Pool پیشفرض کافی است؛ اما روی سرورهای چندسایته، ساخت Pool جداگانه امنیت، کنترل منابع و عیبیابی را بهبود میدهد.
pm.max_children چه کاری انجام میدهد؟
این گزینه حداکثر تعداد Workerهای همزمان PHP-FPM را مشخص میکند. در عمل، این مقدار سقف تعداد درخواستهای PHP است که یک Pool میتواند همزمان اجرا کند.
چرا تغییرات php.ini روی سایت اعمال نمیشود؟
احتمالاً فایل php.ini مربوط به CLI را تغییر دادهاید، در حالی که Nginx از php.ini مربوط به FPM استفاده میکند. پس از تغییر فایل FPM نیز باید سرویس PHP-FPM Reload شود.
جمعبندی
پیکربندی PHP-FPM با Nginx پایه اجرای صحیح و پایدار سایتهای PHP روی وبسرور Nginx است. Nginx درخواست HTTP را دریافت میکند، فایلهای استاتیک را مستقیماً ارائه میدهد و اجرای PHP را از طریق FastCGI به PHP-FPM میسپارد.
برای یک پیکربندی اصولی باید نسخه واقعی PHP، نام سرویس و مسیر Socket را بررسی کنید؛ سپس Nginx را به همان Socket متصل کنید. در سرورهای چندسایته، ساخت Pool مستقل برای هر دامنه باعث جداسازی امنیتی، کنترل بهتر مصرف منابع و ثبت لاگهای مجزا میشود.
همچنین تنظیم صحیح pm.max_children، فعالسازی Slow Log، محدودسازی صفحه Status، جلوگیری از اجرای PHP در پوشههای Upload و بررسی لاگهای Nginx و PHP-FPM نقش مهمی در امنیت و پایداری سرور دارند.
اگر قصد میزبانی سایت PHP یا وردپرس روی زیرساخت اختصاصی دارید، میتوانید متناسب با موقعیت کاربران از VPS ایران، VPS آلمان یا سرویسهای سرور مجازی و اختصاصی استفاده کنید. برای سایتهایی که نیاز به مدیریت فنی سرور ندارند نیز هاست لینوکس و هاست وردپرس گزینه سادهتری هستند.
