Configuring PHP-FPM

The PHP programming language interpreter can work in several modes. It can be integrated into a web server as a special module or used as a separate php-fpm service. The abbreviation FPM stands for Fastcgi Process Manager. This is a service that runs several processes that can execute PHP scripts. Processes can get scripts that need to be executed over TCP or Unix sockets.

Typically, php-fpm is used together with the Nginx web server. In this article, we will look at how to configure PHP-FPM to work as efficiently as possible on your server.

  • Configuring PHP-FPM
    • 1. Installing components
    • 2. Configuration files
    • 3. Creating a pool
    • 4. Configuring the socket
    • 5. Setting up processes
    • 6. Setting up statistics
    • 7. Configuring php. ini
    • 8. Configuring the web server
  • Conclusions

Configuring PHP-FPM

The PHP-FPM process Manager can run multiple handler processes. Usually, for each individual site, it is customary to use a separate handler, this allows you to distribute the load and track statistics for each site. Therefore, there is a common php-fpm configuration file and a configuration file for each handler, which is usually called a pool configuration file. The handler is usually called a pool because in fact, not one process is engaged in processing, but a whole group of processes, each of which has several threads. All this ensures fast execution of scripts.

1. Installing components

The php-fpm service comes with the php interpreter. Installing php-fpm Ubuntu is done with this command:

sudo apt install php-fpm

In addition, we will need an Nginx web server, because php-fpm is most often used together with this web server:

sudo apt install nginx

2. Configuration files

In this tutorial, we will look at configuring PHP-FPM using the Ubuntu example. The main configuration file is located in this path:

ls /etc/php/7.4/fpm/php-fpm.conf

Note that this is not a php.ini file, but a configuration file for FPM processes. The php.ini file is located in the same folder:

ls /etc/php/7.4/fpm/php.ini

But the pool configuration files are located in the /etc/php/7.4/fpm/pool.d / directory. By default there is a default pool file there www.conf:

ls /etc/php/7.4/fpm/pool.d/

You can use it in your configuration or copy it to create new pools.

3. Creating a pool

Copy the pool file, such as losst. conf, to /etc/php/7.4/fpm/pool.d / copy the contents of the file to it www.conf. At the end of the article, I will provide a fully working configuration file, but it is better to use the configuration of your version of PHP:

cp /etc/php/7.4/fpm/pool.d/www.conf /etc/php/7.4/fpm/pool.d/losst.conf

Now open this file in a text editor, such as vim:

sudo vi /etc/php/7.4/fpm/pool.d/losst.conf

First of all, you need to select the pool name in square brackets at the very top of the file, for example, losst, this name can be used in the configuration using the $pool variable, and it will also be displayed in the process manager:

Next, you need to change the group and user on whose behalf the pool processes will run. This is important because the process must have access to the PHP files to be executed. Ubuntu usually uses the www-data user and group for this purpose. A web server is usually started on behalf of the same user:

Usually, if you get the permission denied error when interpreting php files in php-fpm, it means that the php-fpm process is running on behalf of the wrong user or a strict SELinux policy is enabled.

4. Configuring the socket

Next, you need to configure how Nginx or another web server will access PHP-FPM. As I mentioned above, you can configure the waiting for connections on the TCP port. Ports 9000, 9001, 9002, and so on are commonly used. In this case, you need to pass the IP address on which to listen and the port. It is better to use the local IP address 127.0.0.1, so that no one can connect to the service from the Internet. The second option is to use a Unix file socket, then you just need to pass the path to the socket file. This example uses the network socket 127.0.0.1:9000. The type of socket does not matter, but the network one is more convenient to use:

If you use a file socket, the web server must have access to it, so you need to make the file owners of the user and group on behalf of which the web server is running, in this case www-data, and give them all rights to it:

listen.owner = www-data
listen.group = www-data
listen.mode = 0660

If the socket is a network socket, then this is not necessary. For a network socket, you can additionally specify from which addresses you can connect to it. For example, only from 127.0.0.1:

listen.allowed_clients = 127.0.0.1

5. Setting up processes

You can use the pm parameter to configure how many child processes will be started for this pool and when. There are three modes of operation:

  • dynamic-processes are created depending on the load and settings, if there is no load, a certain number of processes are still running;
  • ondemand-processes are created as soon as the load occurs;
  • static – the number of processes is always the same, specified in the settings.

Static mode is not profitable, because regardless of the load, a lot of memory and CPU time is consumed to maintain the operation of processes. More interesting are the ondemand and dynamic modes. Let’s use dynamic mode. This mode has three settings:

  • pm. max_children – a very important parameter that works for all three modes, means the maximum possible number of child processes, if the value is too small, then as the load increases, the limit will be exhausted and your site will start to blunt, if too large-the RAM will be exhausted and something will fall;
  • pm. start_servers-specifies how many processes to start when the service starts;
  • pm. min_spare_servers – the minimum number of processes in idle mode (processing nothing), if the number of processes is less, another one will be created;
  • pm. max_spare_server – the maximum number of processes in standby mode, if the number of processes is greater, the extra ones will be terminated;

For static mode, you only need to specify pm. max_children. For ondemand mode, in addition to pm. max_children, you must specify pm.process_idle_timeout. This parameter means after what period of idle time the process will be completed.

Let’s look at the dynamic mode. You do not need to start many child processes at startup, in most cases 2-3 will be enough:

pm.start_servers = 3

The minimum number of processes in standby mode is also not necessary, it is a reserve so that php-fpm can quickly process new requests without wasting time on starting new processes. However, this value must be at least pm. start_servers, otherwise nothing will work:

pm.min_spare_servers = 3

The maximum number of processes determines how quickly the processes will terminate when the load drops, you can leave 10 processes:

pm.max_spare_servers = 10

Configure the pm.max_children parameter for yourself, usually 20-30 processes are enough, but it all depends on the load and the amount of RAM, if there is not enough memory, it is better to sacrifice performance and set a lower value:

pm.max_children = 30

Almost done. But there is another problem. If child processes run too long, they accumulate memory leaks, and sooner or later the server will run out of memory. To avoid this, you can configure the automatic completion of the process after a certain number of requests, for example, 1000:

pm.max_requests = 1000

6. Setting up statistics

To select the optimal value of pm. max_children, you may need to view real-time statistics on how many processes are running, how many of them are waiting, and how long the queue of pending requests is. To enable statistics output, simply add the following line:

pm.status_path = /status

7. Configuring php. ini

Despite the fact that there is a common php.ini file for all pools, you can change the settings directly in the pool file, using the php_admin_value and php_admin_flag directives. The first one is used for setting string values, and the second one is used for flags. Directives have alternatives: php_value and php_flag, they differ only in that they can be overwritten using the ini_set function, and the values set using directives with the prefix admin cannot be overwritten.

For example:

php_admin_flag[display_errors] = off
php_admin_value[error_log] = /var/log/fpm-php.losst.log
php_admin_flag[log_errors] = on
php_admin_value[memory_limit] = 32M

When all the settings are complete, don’t forget to save the changes and restart php-fpm:

sudo systemctl restart php7.4-fpm

8. Configuring the web server

In order to test everything, you will also have to set up a web server. In the configuration file of the Nginx virtual host, you need to add the following lines::

location /status {
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
}
location ~ .php$ {
fastcgi_split_path_info ^(.+?.php)(/.*)$;
if (!-f $document_root$fastcgi_script_name) {
return 404;
}
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass 127.0.0.1:9000;
}

The first section allows you to view the statistics of php-fpm by opening the /status link in the browser, which we previously specified in the settings. The second section handles all the other php files. The first line of the second section splits the script path by regular expression into two parts: $fastcgi_script_name and $fastcgi_path. We will need the first variable in the next line, where the condition checks whether such a file exists, and if not, it returns 404.

Next, you need to import the fastcgi_params file, which passes all the variables that will then be available in the $_SERVER array from the script. The next line declares another important parameter that is not present in fastcgi_params, because it uses the $fastcgi_script_name variable obtained earlier. This is how php-fpm determines the path to the script to execute, if you do not pass it, you will get a blank screen.

The last fastcgi_pass directive specifies how to pass data to php-fpm, here you can pass the path to the file to the socket on which the service listens, or the IP address and port. In this case, the previously configured 127.0.0.1:9000 is used. After the configuration is complete, restart Nginx:

sudo systemctl restart nginx

Now you can open the statistics page in the browser, as you can see everything works:

You can also create a file phpinfo.php with text> in the web server directory and view the php settings, for example, memory_limit, set in the pool configuration file is running:

The configuration of the web server can be very different depending on your requirements. Here is just a general example to check the performance and correctness of the configuration.

Conclusions

In this short article, we looked at how to configure PHP-FPM with Nginx for optimal processing of PHP scripts on the site. As you can see, despite the rather complex architecture, the program is quite easy to understand. By selecting the correct value of pm. max_children, you can ensure maximum performance for your site and prevent the consumption of all RAM.

Source: losst.ru

(Visited 33 times, 1 visits today)

Leave a Reply

Your email address will not be published. Required fields are marked *