How to manually change the PHP version of a website or web application running in a PHP-FPM pool?

botond published 2024/02/17, Sat - 01:33 time

Content

 

Introductory

A PHP-FPM (FastCGI Process Manager) to run web pages and web applications has many advantages, especially when used with older techniques such as Apache ran as a module PHPwe compare with . One of the most important benefits is that PHP-FPM significantly improves performance and scalability by allowing finer-grained management and optimization of PHP processes. In this way, we can use the server's resources more efficiently, reduce the response time, and our system can remain stable even in the event of heavy traffic. In addition, PHP-FPM dynamically manages child processes, thus adapting to changes in load, which makes the operation of websites and web applications more flexible. Unlike PHP running as an Apache module - where PHP runs inside the web server process - PHP-FPM works as a standalone FastCGI server, which isolates PHP processes from Apache, thereby increasing security and stability. Overall, using PHP-FPM offers a modern, efficient and flexible solution for running websites and web applications, providing significant advantages over older techniques.

We've previously covered how PHP-FPM pools work and how to use PHP-FPM, such as the phpMyAdmin We set up our web database management panel for PHP-FPM operation, which we prepared based on the following description:

In the description above, Debian 10 LAMP as an additional part of the server installation, we set up PHP-FPM for phpMyAdmin, since the PHP system has undergone many updates, so it is appropriate to set our websites and web applications to use the newer PHP branch, including our phpMyAdmin interface.

In this description, we will see in a few steps how we can easily modify our manual settings so that our websites and web applications also work with the correct PHP version. Although it's not the same here now VirtualBoxI will update it on a LAMP server, but I will show it on my other production server, but this is not important from the point of view of the illustration.

In the following, we will review two scenarios:

In the case of both scenarios, phpMyAdmin will be our example web application with which we will make the settings, but we can use it in the same or similar way for any website.

The second of the scenarios can be considered a "continuation" of the description linked above (LAMP server), but the first scenario needs to be reviewed first in order to better understand how it works.

 

 

basic Conditions

The basic condition of the description is that several PHP versions must be installed on the server at the same time. By definition, this guide can only be used in this case. We have already dealt with the installation of several PHP versions in some previous descriptions:

 

Changing the PHP version of a website or web application running in the default PHP-FPM pool

In the first scenario, we look at when our website or web application is not set up in a separate PHP-FPM pool, but the web interface runs in the default pool. But what is the default pool?

Here follows a longer theoretical part. If you want to skip them, skip to this scenario For PHP version settings.

PHP-FPM Apache configuration overview

We've talked about that before how to vary the different PHP-FPM pools according to our needs, in this we reviewed the php-fpm Apache configurations, which have the relevant essence. But since the description just linked is very old, I'd rather copy the php7.4-fpm Apache configuration on this server to see the details through a more recent example. Although this is not the latest (January 2023) version, it is also excellent for illustrating the example.

# Redirect to local php-fpm if mod_php is not available
<IfModule !mod_php7.c>
<IfModule proxy_fcgi_module>
    # Enable http authorization headers
    <IfModule setenvif_module>
    SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1
    </IfModule>

    <FilesMatch ".+\.ph(ar|p|tml)$">
        SetHandler "proxy:unix:/run/php/php7.4-fpm.sock|fcgi://localhost"
    </FilesMatch>
# The default configuration works for most of the installation, however it could
# be improved in various ways. One simple improvement is to not pass files that
# doesn't exist to the handler as shown below, for more configuration examples
# see https://wiki.apache.org/httpd/PHP-FPM
#    <FilesMatch ".+\.ph(ar|p|tml)$">
#        <If "-f %{REQUEST_FILENAME}">
#            SetHandler "proxy:unix:/run/php/php7.4-fpm.sock|fcgi://localhost"
#        </If>
#    </FilesMatch>
    <FilesMatch ".+\.phps$">
        # Deny access to raw php sources by default
        # To re-enable it's recommended to enable access to the files
        # only in specific virtual host or directory
        Require all denied
    </FilesMatch>
    # Deny access to files without filename (e.g. '.php')
    <FilesMatch "^\.ph(ar|p|ps|tml)$">
        Require all denied
    </FilesMatch>
</IfModule>
</IfModule>

There is a slight change compared to the old one, but the essence is the same. So what's going on here?

  • Mod_php Check: In the first line ( ) Apache checks if the mod_php7 module (PHP's integrated Apache module) is active. If this module nem is active, then the following configuration rules apply. This ensures that if mod_php is available, it is preferred for processing PHP files; if not, it switches to using PHP-FPM.
  • Proxy FastCGI Module: THE " " directive checks whether the proxy_fcgi module (the proxy module using the FastCGI protocol) is available and loaded. This module is required so that Apache can redirect the processing of PHP files to the PHP-FPM service.
  • Line of the SetEnvIfNoCase directive: The line allows passing the Authorization HTTP headers from Apache to PHP-FPM. This is especially important for API calls and web applications, where credentials are often passed via HTTP headers.
  • THE directive targets files that have a .php, .phar, or .phtml extension and sets their handler to proxy:unix:/run/php/php7.4-fpm.sock|fcgi://localhost. This means that it forwards these requests over a Unix socket to the local PHP-FPM process.
    Az Unix domain sockets and TCP sockets have already been discussed earlier in this description.
  • The commented part ( ...) presents an optional optimization option. This condition checks if the requested PHP file exists in the file system before redirecting the request to PHP-FPM. With this method, you can avoid unnecessarily burdening the PHP-FPM service in the case of non-existent files.
  • For .phps files ( ) access is denied by default (Require all denied). These files contain raw PHP source code that should not be made directly available for security reasons.
  • PHP files without filename: Similarly, access to PHP files without a filename is also prohibited ( ), which is an additional security measure against unwanted access.

For the purpose of the description here, the first of these points, i.e. the redirection part, is important for us to understand the selection logic of this default pool.

In the case of integration between the Apache web server and PHP-FPM, when no unique pool configuration is explicitly defined for a specific website or web application Virtual hosting file, then the system uses the default www-data PHP-FPM pool. This pool is defined in the default configuration file that is part of the PHP-FPM installation, usually the /etc/php/ /fpm/pool.d/www.conf located on route where indicates the installed PHP version.

Az www.conf file contains the default pool settings, such as user and group IDs (user and group), process management strategy (process management [pm] ), number of child processes (pm.max_children, pm.start_servers, pm.min_spare_servers, pm.max_spare_servers etc.), and other important configuration parameters that affect the operation and management of PHP processes.

When a website or web application generates a PHP request and no explicit pool configuration is defined, the requests directed by Apache to PHP-FPM are processed through the default www-data pool. This ensures that the handling of PHP requests can be centrally configured and managed, even if there is no specific need or requirement for a unique pool configuration.

It is important to note that the default pool configuration can also be customized as needed to better suit our server environment or the specific performance and security requirements of our applications. In addition, in higher performance or security-critical environments, it makes sense to define multiple pools with unique configurations for different websites or applications to optimize the use of system resources and increase application isolation. We will discuss these in the second half of the description.

Check PHP environment before conversion

Before we change anything, it is worth checking the PHP environment of the website or web application selected for modification.

In this example, we first look at the home page of the phpMyAdmin panel:

Check PHP environment - phpMyAdmin home page

Here we can see in the middle panel on the right that this panel works on the 7.4.x PHP version branch. Of course, we only see the version, but the environment in which it is running can only be checked with the help of phpinfo, which offers more detailed information, and which is placed in the web directory of the web interface:

Checking the PHP environment - phpinfo Image 1

Here we can see that the web application really runs with PHP-FPM 7.4. Also, by scrolling down a little, we can see the UNIX user running the system:

Checking the PHP environment - phpinfo Image 2

And here we can also see that the user named www-data really runs this web system, so it runs in the default pool.

Now that we know what environment our web application will run in, we can set it up.

 

 

Change PHP version

If we need to change the default PHP-FPM pool, we don't need to change any configuration files, just run some configuration commands:

Convert/replace PHP-FPM Apache configurations

To "replace" the PHP-FPM Apache configurations, first turn off the active FPM configuration, then turn on the newer or older PHP version you want to set, the one you need. For this operation, it is a2disconf and that a2andconf we use commands. Before that, we can also check the available fpm configuration and which of them are turned on:

find /etc/apache2 -type l -name '*fpm.conf'
find /etc/apache2 -type f -name '*fpm.conf'

Find Apache fpm configurations

With the first command, we find aa / etc / apache2 in the directory with the given ending symbolic links, and then look for the one with the same ending in the same directory structure files, So we have in front of us what we have to turn off, and then what configurations we can choose from. I have exactly these versions on this server. 

The "*fpm.conf" files therefore contain the Apache configurations of redirections to the default www pool, which are created when the various PHP-FPM packages are installed. This default pool serves all requests that do not have a custom fpm pool set up in the virtualhost configuration of that website or web application. The conversion/replacement of individual fpm pools is reviewed in the second chapter of the description.

So if we know which version we want to switch to, then make the switch and restart the relevant services. All of this, of course root-Kent:

a2disconf php7.4-fpm
a2enconf php8.2-fpm
systemctl restart apache2
systemctl restart php7.4-fpm
systemctl restart php8.2-fpm

Change active PHP-FPM configuration

In this example, I switched from 7.4 to 8.2.

There will be another setting here, but I left it right at the end. We can then check the web interfaces.

Checking the PHP environment after the conversion

Let's look at phpMyAdmin:

Check phpMyAdmin home page

Here we can already see that the PHP 8.2.x branch is displayed by the user interface. Then we can also look at the phpinfo page:

check phpinfo page

It also shows the details of the newly set PHP version here.

I mentioned earlier that there is one more setting, let's implement it.

Setting update-alternatives

In order to set everything completely precisely, that's it update-alternatives change the default fpm with the command:

update-alternatives --config php-fpm.sock

And here let's adjust the fpm version to the one set above:

Setting update-alternatives

This command does not directly affect the operation of most virtualhosts, as it only changes the appropriate symbolic link in the /run/php library:

The default path to the php-fpm.sock file

Here, as a result of the command, the link connection was changed, so now the following link chaining is in effect:

/run/php/php-fpm.sock -> /etc/alternatives/php-fpm.sock -> /run/php/php8.2-fpm.sock

This does not directly affect the operation of most virtualhost or Apache configurations, since the php-fpm socket files are set explicitly in most places, it is enough to look at the corresponding line of the configuration at the beginning of the description:

        SetHandler "proxy:unix:/run/php/php7.4-fpm.sock|fcgi://localhost"

So, in most cases, the version can be changed without it, as we saw in the case of phpMyAdmin. However, there may be Apache configurations or virtualhosts that refer to the generic (php-fpm.sock) socket file. In such cases, it is also necessary to set the update-alternatives so that the setting points to the appropriate socket file.

This approach can be useful in development or testing environments that may require frequent switching between PHP versions, or in other environments where multiple projects are running with different PHP version requirements. In this way, the configuration of the web server can remain general, and the PHP-FPM version change can be handled simply with a command line command, minimizing the manual changes required in the configuration and the resulting errors.

However, it is important to keep in mind that although this approach is convenient and flexible, it is necessary to ensure that each web application or project, website that runs on the server, operates in its own FPM pool, so that we can maximize resource utilization and compatibility with individual settings with selected PHP version.

Finally, even after setting update-alternatives, restart the affected services:

systemctl restart apache2
systemctl restart php7.4-fpm
systemctl restart php8.2-fpm

Because update-alternatives only changes the link structure, but not the services.

In the next chapter, we will look at changing the PHP version of a website or web application running in a single PHP-FPM pool.

 

 

Changing the PHP version of a website or web application running in an individual PHP-FPM pool

In the other scenario, we look at the conversion of individual PHP-FPM pools, when a separate pool is set for the website or web application, so the web interface does not work with the default PHP-FPM settings.

We will not discuss the creation of individual PHP-FPM pools here, as we have reviewed this in several other descriptions before, so here we will only review the conversion of the PHP version.

In this section, we will perform the version conversion on the same server, on which I prepared the necessary environment for the sake of the example, so I previously set up a unique PHP-FPM pool for phpMyAdmin, which uses the PHP7.4 version, so in this example we will also switch from PHP 7.4 to 8.2.

Here follows a longer theoretical part. If you want to skip them, skip to this scenario For PHP version settings.

phpMyAdmin Apache configuration overview

In the first scenario, we looked into the Apache configuration of the active PHP-FPM, in which we looked at how the redirection to the default FPM settings works, and here we look at phpMyAdmin's own Apache configuration, where its own pool is explicitly set.

# phpMyAdmin default Apache configuration
Alias /788f9c47f61c4eeb /usr/share/phpmyadmin

<Directory /usr/share/phpmyadmin>
	Options FollowSymLinks
	DirectoryIndex index.php

	<IfModule mod_php7.c>
		AddType application/x-httpd-php .php

		php_flag magic_quotes_gpc Off
		php_flag track_vars On
		php_flag register_globals Off
		php_value include_path .
	</IfModule>

	# PHP-FPM beállítása a saját phpmyadmin pool-hoz
	<IfModule mod_proxy_fcgi.c>
		<FilesMatch "\.(php|html)$">
			SetHandler "proxy:unix:/run/php/php7.4-phpmyadmin-fpm.sock|fcgi://localhost"
		</FilesMatch>
	</IfModule>
	# PHP-FPM beállítás vége

</Directory>

# Authorize for setup
<Directory /usr/share/phpmyadmin/setup>
	<IfModule mod_authn_file.c>
		AuthType Basic
		AuthName "phpMyAdmin Setup"
		AuthUserFile /etc/phpmyadmin/htpasswd.setup
	</IfModule>
	Require valid-user
</Directory>

# Disallow web access to directories that don't need it
<Directory /usr/share/phpmyadmin/libraries>
	Order Deny,Allow
	Deny from All
</Directory>
<Directory /usr/share/phpmyadmin/setup/lib>
	Order Deny,Allow
	Deny from All
</Directory>

Now this is the interesting part:

	# PHP-FPM beállítása a saját phpmyadmin pool-hoz
	<IfModule mod_proxy_fcgi.c>
		<FilesMatch "\.(php|html)$">
			SetHandler "proxy:unix:/run/php/php7.4-phpmyadmin-fpm.sock|fcgi://localhost"
		</FilesMatch>
	</IfModule>
	# PHP-FPM beállítás vége

In this section, phpMyAdmin is set to explicitly refer to the php7.4-phpmyadmin-fpm.sock file. Of course, any file name can be used here, the point is that it is unique, so it differs from the "phpX.Y-fpm.sock" samples shown in the first chapter of the description, which are the socket files of the existing default pools.

Overview of FPM configuration

And our socket file above in this particular example is the /etc/php/7.4/fpm/pool.d/phpmyadmin.conf file, which contains the pool configuration:

phpMyAdmin FPM pool configuration

Here, at the very beginning, the name of the pool itself, the running user and group, and then the socket file itself are set. This file is created when we start/restart the given PHP-FPM service, and the Apache configuration is "connected" to it, through which Apache communicates with the PHP-FPM system. So, whatever name we choose for our socket file, they must match in the two places. In any case, try to set consistent file names.

Here, the additional settings are not important from the point of view of the current description, so I have listed only the beginning.

So, if the PHP-FPM pool of our website or web application is set up in a similar way, and we want to change the PHP version of it manually, then we can continue with the following sections.

 

 

Check PHP environment before conversion

Here we can also review the PHP environment, where we will apparently get the same as in the first scenario:

Check phpMyAdmin home page

check phpinfo

However, here we can also take a look at how php7.4-fpm works:

systemctl status php7.4-fpm.service

php7.4 FPM - Check Pools

Here we can see the point: we also have 3 running phpmyadmin processes - in addition to the default www pool processes - whose name is the same as the name set in the pool configuration shown above. 

If we set the names of our pools and socket files consistently, we will not mix up the settings of our different web applications in the long run. In the case of normal websites, it is rare to have to set them manually, because usually there is something control panel performs these for us, such as ISPConfig also, where this can be conveniently done in the web account settings. But for various web applications, such as phpMyAdmin or webmail, etc., it is advisable to ensure that the given web interface can run with the correct PHP version, environment and authorizations.
Furthermore, a well-designed naming structure can greatly facilitate debugging and system administration, especially for larger systems or multiple servers. Clear names can help you quickly identify which application is using which pool, saving time when diagnosing potential problems.

Change PHP version

If we need to migrate a custom PHP-FPM pool, we need to change some configuration files and then restart the affected services:

Move FPM configuration under the other PHP version

To get a better overview of the whole thing, first one tree and grep with a combination of commands, we list the directories of PHP7.4, PHP8.0 and PHP8.2, from which we filter out the conf.d and mods-available directories containing unnecessary ini files (the ini files of PHP extensions), as well as the temporary ini files (~ .ini), and we only show the .conf and php.ini files that are important for the example.

The command is a /etc/php we can run it from a library:

tree -a 7.4/ 8.0/ 8.2/ -I "conf.d|mods-available" | grep -v "~"

An overview of the PHP library structure

Here, what we need to illustrate the example are the two PHP versions (7.4 and 8.2) and the contents of the "fpm" subdirectories. I also included PHP8.0 in the list just for the sake of example.

Here we can see that our phpmyadmin.conf file is in the FPM pool under PHP7.4.

As a first step, we need to move this file to the parallel directory under the desired target PHP version, which in my example is PHP 8.2. To do this, run the following command, of course replacing it with our own versions:

mv 7.4/fpm/pool.d/phpmyadmin.conf 8.2/fpm/pool.d/

Of course, be careful when using relative directories to start the command from the correct directory, or use absolute access.

After the command, my structure looks like this:

Revisiting the PHP library structure

So the file was moved under the other PHP branch. Then we proceed to the next step.

 

 

Change FPM configuration

In this step, we modify the PHP-FPM configuration file we just moved:

nano /etc/php/8.2/fpm/pool.d/phpmyadmin.conf

Of course, we should substitute our own file here as well.

And here, find the line starting with "listen = /run/php/..." and change it according to the PHP version you want to set:

; Pool-unk neve
[phpmyadmin]

; Futtató felhasználó
user = www-data
group = www-data

; Socket fájl
listen = /run/php/php7.4-phpmyadmin-fpm.sock
listen = /run/php/php8.2-phpmyadmin-fpm.sock

; Socket fájl tulajdonosa és módja
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

; Process management beállítások
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.max_requests = 0

[...]

Modify the Apache configuration

In the next step, similarly, modify the Apache configuration of phpMyAdmin or our own other web application. In this example, with the following command:

nano /etc/apache2/conf-available/phpmyadmin.conf

And here, in the already mentioned and highlighted section, change the name of our socket file to the PHP version you want to set:

[...]
	# PHP-FPM beállítása a saját phpmyadmin pool-hoz
	<IfModule mod_proxy_fcgi.c>
		<FilesMatch "\.(php|html)$">
			SetHandler "proxy:unix:/run/php/php7.4-phpmyadmin-fpm.sock|fcgi://localhost"
			SetHandler "proxy:unix:/run/php/php8.2-phpmyadmin-fpm.sock|fcgi://localhost"	
		</FilesMatch>
	</IfModule>
	# PHP-FPM beállítás vége
[...]

Of course, we can give our file any name, the main thing is to have the same names in the Apache configuration and the FPM configuration, as well as to follow the previously mentioned principle of consistency, so that our system remains transparent later on.

Restart Services

Finally, restart the affected services:

  • Apache
  • Source PHP-FPM (from where we converted our pool)
  • Target PHP-FPM (where we moved our pool to)
systemctl restart apache2
systemctl restart php7.4-fpm.service
systemctl restart php8.2-fpm.service

Here it is important to restart both FPMs, so that on the one hand the pools in each of them are updated, and so that no conflict can arise, for example, by having the same pool in two FPMs, because the previous one was, say, not updated, etc.

 

Control

Finally, let's check everything. Let's look at the web parts:

Checking phpMyAdmin after settings

checking phpinfo after settings

Everything is fine with them, the web interface runs on the PHP 8.2 branch.

Let's also look at PHP-FPMs:

systemctl status php7.4-fpm.service
systemctl status php8.2-fpm.service

Checking PHP-FPM after settings

As you can see, our pool named "phpmyadmin" has been transferred from the management of FPM 7.4 to 8.2.

With this, our web interface - in this case phpMyAdmin - remains in a separate pool even after the installation of the newer version, so we can continue to operate it isolated from the default PHP-FPM settings and from the PHP environment of other websites. So if, for example, we need to set some php.ini value, we can already do this separately in the configuration of the pool of the given web application. We have already said a few words about this, here we can review the process of such settings:

 

 

Conclusion

A PHP-FPM (FastCGI Process Manager) is an extremely powerful and flexible tool for PHP for dynamically and efficiently serving web applications. its key ability to fine-tune process management, optimize resource usage, and improve response times makes it essential for serving modern web applications. Working with custom pool configurations, using a modular conf.d directory structure, and flexible switching between PHP versions allow developers and system administrators to precisely control and customize the server environment to best suit different applications and scenarios. needs.

The version changer settings presented here can be used in all places where PHP-FPM was previously manually configured, so these websites or web applications can also run in an up-to-date PHP environment.

These settings are extremely simple for both scenarios, but I've tried to provide a lot of theoretical parts to make it easier for those new to these parts to understand how they work.