In this tutorial, I am going to show you how you can create a pool to segregate php process for each wordpress website. This totorial is setup using PHP-FPM8.1. This may not work if you are using older version of PHP.
Install PHP-FPM
Install the latest version of PHP FPM. If there is a new version, select that version for installation.
sudo apt-get install php8-1-fpm
Check Service Status:
sudo systemctl status php8-1-fpm.service
Output:
rahil@localhost:$ sudo systemctl status php8.1-fpm.service
● php8.1-fpm.service - The PHP 8.1 FastCGI Process Manager
Loaded: loaded (/lib/systemd/system/php8.1-fpm.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2023-09-25 18:28:47 UTC; 23min ago
Docs: man:php-fpm8.1(8)
Process: 14322 ExecStartPost=/usr/lib/php/php-fpm-socket-helper install /run/php/php-fpm.sock /etc/php/8.1/fpm/pool.d/www.conf 81 (code=exited, status=0/SUCCESS)
Main PID: 14319 (php-fpm8.1)
Status: "Processes active: 0, idle: 2, Requests: 0, slow: 0, Traffic: 0req/sec"
Tasks: 3 (limit: 1013)
Memory: 11.1M
CPU: 83ms
CGroup: /system.slice/php8.1-fpm.service
├─14319 "php-fpm: master process (/etc/php/8.1/fpm/php-fpm.conf)" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""
├─14320 "php-fpm: pool www" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "">
└─14321 "php-fpm: pool www" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "">
Sep 25 18:28:47 localhost systemd[1]: Starting The PHP 8.1 FastCGI Process Manager...
Sep 25 18:28:47 localhost systemd[1]: Started The PHP 8.1 FastCGI Process Manager.
Configuring PHP-FPM Pool
Create group for WordPress site:
sudo groupadd wordpress_demo
sudo useradd -g wordpress_demo wordpress_demo
Next, let’s navigate to the PHP-FPM folder path to create a new configuration file:
cd /etc/php/8.1/fpm/pool.d/
Inside this folder create a new configuration file called wordpress_demo_pool.conf
sudo vi wordpress_demo_pool.conf
[wordpress_demo_site]
user = wordpress_demo
group = wordpress_demo
listen = /var/run/php/php8.1-fpm-wordpress-demo-site.sock
listen.owner = www-data
listen.group = www-data
php_admin_value[disable_functions] = exec,passthru,shell_exec,system
php_admin_flag[allow_url_fopen] = off
; Choose how the process manager will control the number of child processes.
pm = dynamic
pm.max_children = 75
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.process_idle_timeout = 10s
env[HOSTNAME] = $HOSTNAME
env[TMP] = /tmp
Insert the below command. Definition of each item is provided below:
- [wordpress_demo_site]: This is a unique identifier for the pool, ensuring no two pools share the same name.
- user and group: Specifies which user and group the pool operates under.
- listen: Defines the socket file’s name associated with this pool.
- listen.owner and listen.group: These should align with the user and group that NGINX operates under. For this scenario, it’s www-data.
- php_admin_value: Enables the setting of specific PHP configuration parameters.
- php_admin_flag: Used to define PHP boolean settings.
pm: Manages processes, with the “Dynamic” value indicating that child process numbers adjust based on subsequent directives. - pm.max_children: Indicates the peak number of concurrently active child processes.
- pm.start_servers: Represents the count of child processes initiated upon startup.
- pm.min_spare_servers: Denotes the least number of idle child processes. If idle processes drop below this, new ones are spawned.
- pm.max_spare_servers: Represents the upper limit for idle child processes. If this number is exceeded, some processes will be terminated.
- pm.process_idle_timeout: Specifies the ideal maximum for idle server processes. This is relevant only when the pm setting is “dynamic”. Beyond these configurations, it’s feasible to relay certain system environment variables to the php-fpm service, like using env[‘PHP_FOO’] = $bar. For instance, integrating the subsequent options in the mentioned configuration will assign the hostname and temporary directory path to the PHP environment.
PHP-FPM (FastCGI Process Manager) is an alternative PHP FastCGI implementation with some additional features useful for sites with high traffic. One of the key features of PHP-FPM is its ability to manage PHP processes. The process manager (pm
) is responsible for controlling the number of child processes, which in turn handle the PHP requests.
Here’s a breakdown of the PHP-FPM process manager for more details:
- Types of Process Managers:
PHP-FPM offers several ways to manage PHP processes:
- Static (
pm = static
): A fixed number of child processes are created. The number is specified by thepm.max_children
directive. This mode is straightforward and can be efficient if you know the exact number of processes you need. However, it lacks flexibility. - Dynamic (
pm = dynamic
): The number of child processes is set dynamically based on the following directives:pm.max_children
,pm.start_servers
,pm.min_spare_servers
, andpm.max_spare_servers
. This mode offers more flexibility and can adjust based on the demand. - On-demand (
pm = ondemand
): Processes are spawned as needed. No child processes are created at startup, but they’re created on demand when there’s a request. This mode is the most flexible and can be efficient for sites with fluctuating traffic.
Benefits:
- Adaptability: PHP-FPM can adjust the number of child processes based on the traffic, ensuring efficient resource usage.
- Performance: By managing processes effectively, PHP-FPM can handle a large number of requests without overloading the server.
- Isolation: Each PHP request can be processed in a separate child process, providing isolation and security.
- Custom Configuration: PHP-FPM allows for pool-specific configurations, enabling fine-tuned settings for different websites or applications on the same server.
In summary, the PHP-FPM process manager provides a way to efficiently handle PHP requests by managing child processes. Depending on the configuration and the type of process manager chosen, PHP-FPM can offer a balance between performance and flexibility.
Restart fpm service to apply new changes:
sudo systemctl restart php8.1-fpm && sudo systemctl status php8.1-fpm --no-pager
Configure Nginx for PHP-FPM
server {
listen 80;
root /var/www/html/wordpress_blog/public_html;
index index.php index.html;
server_name blog.wordpress.xyz;
access_log /var/log/nginx/wordpress_blog.access.log;
error_log /var/log/nginx/wordpress_blog.error.log;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.1-fpm-wordpress-demo-site.sock;
}
location ~ /\.ht {
deny all;
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
}
}
Next, test Nginx configuration.
sudo nginx -t
Restart Nginx Service:
sudo systemctl restart nginx
Testing PHP-FPM Nginx Configuration
To verify that the aforementioned NGINX configuration file is utilizing the newly established FPM pool, generate a PHP info file within the web root. In the above NGINX configuration file, I have designated /var/www/html/wordpress_blog/public_html as the web root. Modify this value to suit your setup.
echo "<?php echo phpinfo();?>" > info.php
Setting Permissions For WordPress
How we have set up PHP-FPM, it is crucial to set permissions to public_html
folder. Execute the below commands:
sudo chmod -R 755 *
sudo chmod -R 664 *.php *.txt *.html
sudo chown -R wordpress_demo:www-data *